module klang.klang.编译.klang编译_;
import 全局;
import std.conv: ·to = to;
import std.functional: ·fd = toDelegate;
import ··Klang节点_ = klang.klang.语法节点.Klang节点_;
import klang.编译.编译.编译_: 编译器_;
import 核心 = klang.编译.核心.核心_;
import 基础节点 = klang.编译.语法节点.节点_;
import 路径模块 = klang.编译.路径.路径_;
import 系统 = klang.编译.系统.系统_;
import klang.编译.核心.核心_: 整数_, 词典_, 查找, 循环每个, 创建词典, 开始包含, 查找数组索引, 创建词典从关联数组;
import klang.编译.路径.路径_: 路径_, 正规化路径和片段, 获取目录路径;
import klang.编译.语法节点.节点_: 节点_, 令牌_, 源文件_, 令牌种类_, 节点数组_, 是失踪列表, 是失踪节点, 文本字面量_, 数字字面量_, 字面量类节点_;
import klang.编译.类型.枚举值.枚举值_: SK, TK, 字符_, 令牌标志_;
import klang.编译.类型.类型_: 编译器基类_, 前端编译器接口_;
import 编译数字 = 编译数字.编译;
import klang.编译.诊断集.诊断集_: 诊断集_;
import klang.编译.诊断.诊断_: 诊断消息_, 诊断_;
import klang.klang.工具.klang工具_: 设置节点标志;
import klang.klang.常量值.Klang常量值_: 转换SK为KSK, 标识符转KSK, 获取组合标点令牌, 获取KSK关键字文本;
import klang.klang.类型.klang类型_: KSK, 扩展名_, 节点标志_, AssertFlags, 版本容器块种类_;
import klang.klang.语法节点.Klang节点_: 创建节点, Klang源文件_, Klang节点_, 语句_, 导入声明基类_, 导入声明_, 导入从声明_, 导入成员基类_, 导入版本成员_, 导入成员_, 导入成员块_, 导入从成员基类_, 导入从版本成员_, 导入从成员_, 导入从成员块_, 源码级版本语句_, 版本表达式语句_, 版本语句_, 块_, 指令语句_, 程序声明_, 测试单元语句_, 变量语句_, 变量声明_, 变量声明列表_, 标识符_, 前缀一元表达式_, 后缀一元表达式_, 表达式_, 字面量类表达式基类_, klang小数字面量_, klang数字字面量_, klang文本字面量_, 字符字面量_, 正则表达式字面量_, Klang令牌_, 部分输出表达式_, 二元表达式_, 条件表达式_, 属性访问表达式_, 调用表达式_, 类型查询表达式_, 类型断言表达式_, 非空表达式_, 类型转换表达式_, 箭头函数_, 签名声明_, 类型节点_, 类型列表_, 指针类型_, 变长参数_, 动态数组类型_, 数组类型_, 词典类型_, 静态二元表达式类型节点_, 联合类型_, 字面量类型_, 类型限定类型_, 元组类型节点_, 无替换模板字面量_, 类型引用_, 限定名_, 括号类型_, 函数类型_, 类型形参_, 形参声明_, 区间类型节点_, 展开表达式_, 开放括号表达式_, 截取表达式_, 元素访问表达式_, 数组字面量表达式_, 动态类字面量表达式_, 词典键值表达式_, 函数表达式_, 接口字面量表达式_, 结构字面量表达式_, 属性赋值_, 简洁属性赋值_, 新建表达式_, 表达式包含类型实参_, 符号引用表达式_, 省略表达式_, 模板表达式_, 模板中_, 模板尾_, 模板头_, 修饰符_, 是展开表达式, 是构建声明, 是释放声明, 获取类型引用, 获取函数类型, 获取类型列表, 获取括号类型, 修饰符标志_, 函数声明_, 方法声明_, 属性声明_, 构建声明_, 释放声明_, 枚举声明_, 接口声明_, 对象声明_, 结构声明_, 类型声明_, 别名声明_, 继承子句_, 枚举成员_, 声明_, 失踪声明_, 索引签名_, 运算符签名_, 运算符签名元素_, 外部修饰符声明_, 空语句_, 如果语句_, 迭代类语句_, 循环属于_, 循环语句_, 当循环语句_, 跳出语句_, 继续语句_, 延迟语句_, 删除语句_, 返回语句_, 假如语句_, 若是块_, 抛出语句_, 断言语句_, 同步语句_, 尝试语句_, 捕获子句_, 调试语句_, 标签语句_, 表达式语句_, 表达式列表表达式_, 若是或默认子句_, 若是子句_, 默认子句_, 是类型查询表达式, 是符号引用表达式, 获取符号引用表达式, 是类型引用, 是表达式包含类型实参, 获取表达式包含类型实参, 是括号类型, 是类型限定类型, 获取类型限定类型, 是动态数组类型节点, 是数组类型节点, 是词典类型节点, 是元素访问表达式, 获取元素访问表达式, 获取截取表达式, 是截取表达式, 是字面量种类, 是模板字面量种类, 是逻辑运算符, 是赋值运算符;
编译器_ 编译器 = ··null!(编译器_);
KSK 当前令牌 = KSK.未知__;
KSK 结尾令牌 = KSK.未知__;
bool 允许美元标识符 = false;
bool 是版本另如容器块 = false;
bool 有静态表达式 = false;
bool 是在继承子句上下文 = false;
bool 正在编译取址表达式 = false;
bool 正在编译构建声明 = false;
bool 允许词典键值表达式 = false;
bool 包含词典键值表达式 = false;
bool 包含展开表达式 = false;
bool 允许类型计算 = false;
bool 已有启动声明 = false;
long 全局的节点开始位置 = 0;
基础节点.节点数组_!(修饰符_) 全局修饰符数组 = ··null!(基础节点.节点数组_!(修饰符_));
核心.词典_!(bool) 非括号箭头;
核心.词典_!(dstring) 文件设置的版本标识符;
bool 开始编译约束类型 = false;
Klang源文件_ 源文件;
long 编译上下文 = 0;
static this() {
    非括号箭头 = 创建词典!(bool)();
    文件设置的版本标识符 = 创建词典!(dstring)();
}
enum 签名标志_ : int {
    无_ = 0,
    产生 = 1,
    等待 = 2,
    类型 = 4,
    忽略失踪括号 = 16,
    初始函数 = 64
}
enum 编译上下文_ : int {
    源码顶级语句_ = 0,
    测试单元语句_ = 1,
    程序集顶级语句_ = 2,
    块语句组 = 3,
    假如子句组 = 4,
    假如子句语句组 = 5,
    枚举成员组 = 6,
    继承子句组元素 = 7,
    变量声明组 = 8,
    实参表达式组 = 9,
    接口字面量成员组 = 10,
    结构对象字面量成员组 = 11,
    汉英词典元素_ = 12,
    词典字面量元素 = 13,
    数组字面量成员组 = 14,
    形参组 = 15,
    类型形参组 = 16,
    类型实参组 = 17,
    继承子句组 = 18,
    对象体成员_ = 19,
    类型声明成员_ = 20,
    接口声明成员_ = 21,
    编译导入从语句_ = 22,
    编译导入语句_ = 23,
    运算符签名列表 = 24,
    数量 = 25
}
enum 逗号编译结果_ : int {
    是逗号_ = 1,
    逗号后就结束_ = 2,
    是结尾_ = 3,
    错误_ = 4
}
enum 三元值_ : int {
    假_ = 0,
    真_ = 1,
    未知_ = 2
}
class 前端编译器_ : 前端编译器接口_ {
    编译器_ 编译器;
    this() { }
    this(编译器基类_ 编译) {
        this.编译器 = (cast(编译器_)(编译));
        .编译器 = this.编译器;
    }
    基础节点.源文件_ 编译源文件() {
        assert((this.编译器.当前源文件 !is ··null!(基础节点.源文件_)) && this.编译器.当前源文件.目标 == TK.Klang, "不是前端'klang'支持的目标"c);
        .源文件 = (cast(Klang源文件_)(this.编译器.当前源文件));
        if (.是声明文件(编译器.当前文件名)) {
            源文件.是声明文件 = true;
            .设置标志(节点标志_.Ambient);
        }
        .下个令牌();
        源文件.语句组 = ·to!(基础节点.节点数组_!(基础节点.节点_))(.编译源文件平台());
        源文件.文件结尾令牌 = 编译器.编译文件结尾令牌();
        源文件.开始 = 0;
        源文件.结束 = 源文件.文件结尾令牌.结束;
        源文件.标识符数量 = 编译器.标识符数量;
        源文件.文件设置的版本标识符 = .文件设置的版本标识符;
        return .源文件;
    }
    void 清理() {
        编译器.清理();
        .当前令牌 = KSK.未知__;
        .结尾令牌 = KSK.未知__;
        .允许美元标识符 = false;
        .是版本另如容器块 = false;
        .有静态表达式 = false;
        .是在继承子句上下文 = false;
        .正在编译构建声明 = false;
        .正在编译取址表达式 = false;
        .正在编译构建声明 = false;
        .全局的节点开始位置 = 0;
        .全局修饰符数组 = ··null!(基础节点.节点数组_!(修饰符_));
        .非括号箭头 = 创建词典!(bool)();
        .文件设置的版本标识符 = 创建词典!(dstring)();
        .源文件 = ··null!(Klang源文件_);
        .编译上下文 = 0;
        .已有启动声明 = false;
    }
}
bool 是声明文件(路径模块.路径_ 路径) {
    dstring 扩展 = 扩展名_.DK;
    dstring 结果 = 路径模块.获取任意一个扩展名从路径(路径.原型, [扩展], 系统.sys.是使用区分大小写文件系统);
    return 结果 == 扩展;
}
long 获取节点开始() {
    return 编译器.获取节点开始();
}
long 获取文本开始() {
    return 编译器.获取文本开始();
}
void 报告当前令牌编译错误(诊断消息_ 消息, dstring 消息实参 = " "d) {
    return 编译器.报告当前令牌编译错误(消息, 消息实参);
}
void 报告当前位置编译错误(long 起点, long 长, 诊断消息_ 消息, dstring[] 消息实参) {
    消息实参 = 消息实参.dup;
    return 编译器.报告当前位置编译错误(起点, 长, 消息, 消息实参);
}
void 编译错误在(long 起点, long 结尾, 诊断消息_ 消息, dstring 消息实参 = " "d) {
    return 编译器.编译错误在(起点, 结尾, 消息, 消息实参);
}
诊断_[] 获取收集的诊断消息() {
    return 编译器.获取收集的诊断消息();
}
KSK 令牌() {
    return .当前令牌;
}
KSK 下个令牌() {
    .当前令牌 = .预扫描KSK(编译器.下个令牌());
    return .当前令牌;
}
T 完成节点(T)(T 节点, long 开始, long 结尾 = -2) {
    return 编译器.f·完成节点!(T)(节点, 开始, 结尾);
}
T 编译令牌节点(T)() {
    return 编译器.f·编译令牌节点!(T)();
}
基础节点.令牌_!(TK) 编译可选令牌节点(TK)(TK t) {
    return 编译器.f·编译可选令牌节点!(TK)(t);
}
bool 编译确定的(KSK ksk, 诊断消息_ 诊断消息 = ··null!(诊断消息_), bool 应该前进 = true) {
    if (.令牌() == ksk) {
        if (应该前进) {
            .下个令牌();
        }
        return true;
    }
    if (诊断消息 !is ··null!(诊断消息_)) {
        .报告当前令牌编译错误(诊断消息);
    }
    else {
        dstring 参数 = 获取KSK关键字文本(ksk);
        if (参数 is ··null!(dstring)) {
            参数 = "未知令牌"d;
        }
        .报告当前令牌编译错误(诊断集_.a0_expected, 参数);
    }
    return false;
}
Klang令牌_!(T) 编译确定klang令牌(T)(T tsk, 诊断消息_ 诊断消息 = ··null!(诊断消息_)) {
    Klang令牌_!(T) n = .编译可选klang令牌!(T)(tsk);
    if (n !is ··null!(Klang令牌_!(T))) {
        return n;
    }
    if (诊断消息 is ··null!(诊断消息_)) {
        诊断消息 = 诊断集_.a0_expected;
    }
    return .创建失踪klang节点!(Klang令牌_!(T))(tsk, true, 诊断消息);
}
Klang令牌_!(T) 编译klang令牌节点(T)(T tsk) {
    long 开始 = .获取节点开始();
    Klang令牌_!(T) n = new Klang令牌_!(T)(tsk);
    .下个令牌();
    return .完成节点!(Klang令牌_!(T))(n, 开始);
}
Klang令牌_!(T) 编译可选klang令牌(T)(T tsk) {
    if (.令牌() == tsk) {
        return .编译klang令牌节点!(T)(tsk);
    }
    return ··null!(Klang令牌_!(T));
}
bool 编译可选的(KSK ksk) {
    if (.令牌() == ksk) {
        .下个令牌();
        return true;
    }
    return false;
}
T 推断助手(T)(T delegate() 回调, bool 是向前看) {
    KSK 储存当前令牌 = .当前令牌;
    T 结果 = 编译器.f·推断助手!(T)(cast(T delegate())(回调), 是向前看);
    if ((结果 is ··null!(T)) || 是向前看) {
        .当前令牌 = 储存当前令牌;
    }
    return 结果;
}
T 向前看(T)(T delegate() 回调) {
    return .推断助手!(T)(cast(T delegate())(回调), true);
}
T 尝试编译(T)(T delegate() 回调) {
    return .推断助手!(T)(cast(T delegate())(回调), false);
}
bool 有间隔() {
    return (.获取令牌标志() & 令牌标志_.令牌前有杂项) != 0;
}
KSK 预扫描大于号() {
    bool 结果 = 编译器.预扫描(">>>="d);
    if (结果) {
        .当前令牌 = KSK.右右右尖等号;
        return .当前令牌;
    }
    结果 = 编译器.预扫描(">>>"d);
    if (结果) {
        .当前令牌 = KSK.右右右尖号;
        return .当前令牌;
    }
    结果 = 编译器.预扫描(">>="d);
    if (结果) {
        .当前令牌 = KSK.右右尖等号;
        return .当前令牌;
    }
    结果 = 编译器.预扫描(">>"d);
    if (结果) {
        .当前令牌 = KSK.右右尖号;
        return .当前令牌;
    }
    结果 = 编译器.预扫描(">="d);
    if (结果) {
        .当前令牌 = KSK.右尖等号;
        return .当前令牌;
    }
    return .当前令牌;
}
KSK 预扫描KSK(SK sk) {
    if (sk == SK.连续运算符) {
        return 获取组合标点令牌(.获取令牌值());
    }
    if (sk == SK.标识符) {
        return 标识符转KSK(.获取令牌值(), KSK.标识符);
    }
    return 转换SK为KSK(sk);
}
T 创建失踪节点(T)(SK sk, bool 报告当前位置错误, 诊断消息_ 诊断消息, dstring 消息实参 = ""d) {
    return 编译器.f·创建失踪节点!(T)(sk, 报告当前位置错误, 诊断消息, 消息实参);
}
T 创建失踪klang节点(T)(KSK tsk, bool 报告当前位置错误, 诊断消息_ 诊断消息, dstring 消息实参 = ""d) {
    long 节点开始 = .获取节点开始();
    Klang节点_ n = 创建节点!(Klang节点_)(tsk);
    if (消息实参 == ""d) {
        消息实参 = 获取KSK关键字文本(tsk);
    }
    if (报告当前位置错误) {
        .报告当前位置编译错误(.获取节点开始(), 0, 诊断消息, [消息实参]);
    }
    else if (诊断消息 !is ··null!(诊断消息_)) {
        .报告当前令牌编译错误(诊断消息, 消息实参);
    }
    return (cast(T)(.完成节点!(Klang节点_)(n, 节点开始)));
}
基础节点.节点数组_!(T) 创建失踪列表(T)() {
    return 编译器.f·创建失踪列表!(T)();
}
基础节点.节点数组_!(T) 创建节点数组(T)(T[] 元素组, long 开始, long 结束 = -2) {
    return 编译器.f·创建节点数组!(T)(元素组, 开始, 结束);
}
bool 计算编译错误(基础节点.节点_ 计算的节点) {
    return 编译器.计算编译错误(计算的节点);
}
void 收集子节点数据(基础节点.节点_ 计算的节点) {
    return 编译器.收集子节点数据(计算的节点);
}
令牌标志_ 获取令牌标志() {
    return 编译器.获取令牌标志();
}
dstring 获取令牌值() {
    return 编译器.获取令牌值();
}
long 获取令牌开始() {
    return 编译器.获取令牌开始();
}
bool 令牌是标识符或关键字(KSK ksk) {
    return ksk >= KSK.标识符 && ksk <= KSK.类型_;
}
··Klang节点_.Klang标识符_ 创建标识符(bool 是标识符, 诊断消息_ 诊断消息 = ··null!(诊断消息_)) {
    ··Klang节点_.Klang标识符_ id = new ··Klang节点_.Klang标识符_(编译器.创建标识符(是标识符, 诊断消息));
    if (开始包含(id.标识符.内容, "__"d)) {
        设置节点标志(id, 节点标志_.是空的);
    }
    else if (开始包含(id.标识符.内容, "_"d)) {
        设置节点标志(id, 节点标志_.私有的);
    }
    .当前令牌 = .预扫描KSK(编译器.令牌());
    return id;
}
··Klang节点_.Klang标识符_ 编译标识符(诊断消息_ 诊断消息 = ··null!(诊断消息_)) {
    if (.令牌() == KSK.美元) {
        long 开始 = .获取令牌开始();
        .下个令牌();
        ··Klang节点_.Klang标识符_ id = .创建标识符(.令牌() == KSK.文本字面量, 诊断消息);
        id.开始 = 开始;
        id.标志 |= (cast(ulong)(节点标志_.文本内容标识符));
        return id;
    }
    return .创建标识符(.是标识符(), 诊断消息);
}
dstring 初始标识符文本(dstring 内容) {
    return 编译器.初始标识符文本(内容);
}
基础节点.文本字面量_ 编译文本字面量() {
    基础节点.文本字面量_ str = 编译器.编译文本字面量();
    .当前令牌 = .预扫描KSK(编译器.令牌());
    return str;
}
基础节点.数字字面量_ 编译数字字面量() {
    基础节点.数字字面量_ num = 编译器.编译数字字面量();
    .当前令牌 = .预扫描KSK(编译器.令牌());
    return num;
}
节点标志_ 获取文本字面量类后缀(dstring 后缀) {
    if (后缀 == "c"d) {
        return 节点标志_.C;
    }
    else if (后缀 == "w"d) {
        return 节点标志_.W;
    }
    else if (后缀 == "d"d) {
        return 节点标志_.D;
    }
    return 节点标志_.无;
}
节点标志_ 获取小数字面量后缀(dstring 后缀) {
    if (后缀 == "f"d || 后缀 == "F"d) {
        return 节点标志_.F;
    }
    if (后缀 == "fi"d || 后缀 == "FI"d || 后缀 == "Fi"d || 后缀 == "fI"d || 后缀 == "if"d || 后缀 == "IF"d || 后缀 == "iF"d || 后缀 == "If"d) {
        return 节点标志_.FI;
    }
    if (后缀 == "i"d || 后缀 == "I"d) {
        return 节点标志_.I;
    }
    return 节点标志_.无;
}
节点标志_ 获取整数字面量后缀(dstring 后缀) {
    if (后缀 == "U"d || 后缀 == "u"d) {
        return 节点标志_.U;
    }
    if (后缀 == "L"d || 后缀 == "l"d) {
        return 节点标志_.L;
    }
    if (后缀 == "UL"d || 后缀 == "ul"d || 后缀 == "uL"d || 后缀 == "Ul"d || 后缀 == "LU"d || 后缀 == "lu"d || 后缀 == "Lu"d || 后缀 == "lU"d) {
        return 节点标志_.UL;
    }
    return 节点标志_.无;
}
bool 文本是十六进制的(dstring 内容) {
    {
        for (int i = 0; i < 内容.length; ++i) {
            immutable(dchar) ch = 内容[i];
            if (!(ch >= 字符_.数_0 && ch <= 字符_.数_9 || ch >= 字符_.a && ch <= 字符_.f || ch >= 字符_.A && ch <= 字符_.F)) {
                return false;
            }
        }
    }
    return true;
}
bool 文本是八进制的(dstring 内容, ref dstring 新内容) {
    dstring 值内容 = [];
    {
        for (int i = 0; i < 内容.length; ++i) {
            immutable(dchar) ch = 内容[i];
            if (!((ch >= 字符_.数_0 && ch <= 字符_.数_7) || ch == 字符_.下划线)) {
                新内容 = 内容;
                return false;
            }
            if (ch != 字符_.下划线) {
                值内容 = .追加!(immutable(dchar))(值内容, ch);
            }
        }
    }
    新内容 = ·to!(dstring)(值内容);
    return true;
}
bool 文本是二进制的(dstring 内容, ref dstring 新内容) {
    dstring 值内容 = [];
    {
        for (int i = 0; i < 内容.length; ++i) {
            immutable(dchar) ch = 内容[i];
            if (!((ch >= 字符_.数_0 && ch <= 字符_.数_1) || ch == 字符_.下划线)) {
                新内容 = 内容;
                return false;
            }
            if (ch != 字符_.下划线) {
                值内容 = .追加!(immutable(dchar))(值内容, ch);
            }
        }
    }
    新内容 = ·to!(dstring)(值内容);
    return true;
}
字面量类表达式基类_ 可能是是十六进制或八进制或二进制数字() {
    long 可能开始 = .获取节点开始();
    .下个令牌();
    if (!.有间隔() && .令牌() == KSK.标识符) {
        dstring 内容 = .获取令牌值();
        if (内容.length >= 2) {
            immutable(dchar) ch = 内容[0];
            内容 = 内容[1 .. $];
            if ((ch == 字符_.x || ch == 字符_.X) && .文本是十六进制的(内容)) {
                klang数字字面量_ n = 创建节点!(klang数字字面量_)(KSK.数字字面量);
                n.内容 = "0x"d ~ 内容;
                try {
                    n.整数值 = 编译数字.编译!(ulong)(内容, 16);
                }
                catch(Throwable e) {
                    n.整数值 = 0;
                }
                .下个令牌();
                klang数字字面量_ 结果 = .完成节点!(klang数字字面量_)(n, 可能开始);
                return 结果;
            }
            else if (ch == 字符_.b || ch == 字符_.B) {
                dstring 新内容 = ""d;
                bool 成功 = .文本是二进制的(内容, 新内容);
                if (成功) {
                    klang数字字面量_ n = 创建节点!(klang数字字面量_)(KSK.数字字面量);
                    n.内容 = "0b"d ~ 内容;
                    try {
                        n.整数值 = 编译数字.编译!(ulong)(新内容, 2);
                    }
                    catch(Throwable ee) {
                        n.整数值 = 0;
                    }
                    .下个令牌();
                    klang数字字面量_ 结果 = .完成节点!(klang数字字面量_)(n, 可能开始);
                    return 结果;
                }
            }
            else if (ch == 字符_.o || ch == 字符_.O) {
                dstring 新内容 = ""d;
                bool 成功 = .文本是八进制的(内容, 新内容);
                if (成功) {
                    klang数字字面量_ n = 创建节点!(klang数字字面量_)(KSK.数字字面量);
                    n.内容 = "0o"d ~ 内容;
                    try {
                        n.整数值 = 编译数字.编译!(ulong)(新内容, 8);
                    }
                    catch(Throwable eee) {
                        n.整数值 = 0;
                    }
                    .下个令牌();
                    klang数字字面量_ 结果 = .完成节点!(klang数字字面量_)(n, 可能开始);
                    return 结果;
                }
            }
        }
        klang数字字面量_ n = 创建节点!(klang数字字面量_)(KSK.数字字面量);
        n.内容 = 内容;
        n.整数值 = 0;
        .下个令牌();
        .编译错误在(可能开始, .获取节点开始(), 诊断集_.Unexpected_token);
        klang数字字面量_ 结果 = .完成节点!(klang数字字面量_)(n, 可能开始);
        return 结果;
    }
    else {
        klang数字字面量_ n = 创建节点!(klang数字字面量_)(KSK.数字字面量);
        n.内容 = "0"d;
        n.整数值 = 0;
        klang数字字面量_ 结果 = .完成节点!(klang数字字面量_)(n, 可能开始);
        return 结果;
    }
}
··Klang节点_.Klang标识符_ 尝试编译数字字面量后缀() {
    ··Klang节点_.Klang标识符_ delegate() 内部编译;
    ··Klang节点_.Klang标识符_ 内部编译·func() {
        .下个令牌();
        if (!.有间隔() && .令牌() == KSK.标识符) {
            ··Klang节点_.Klang标识符_ 整数后缀标识符 = .编译标识符();
            dstring 内容 = 整数后缀标识符.标识符.内容;
            节点标志_ 整数后缀标志 = .获取整数字面量后缀(内容);
            if (整数后缀标志 != 节点标志_.无) {
                return 整数后缀标识符;
            }
        }
        return ··null!(··Klang节点_.Klang标识符_);
    }
    内部编译 = &内部编译·func;
    return .尝试编译!(··Klang节点_.Klang标识符_)(cast(··Klang节点_.Klang标识符_ delegate())(内部编译));
}
字面量类表达式基类_ 编译数字字面量表达式() {
    assert(.令牌() == KSK.数字字面量, "编译数字字面量表达式错误"c);
    long 数字开始 = .获取节点开始();
    bool 有后缀 = false;
    bool 后缀错误 = false;
    if ((.获取令牌标志() & 令牌标志_.是小数_) != 0) {
        dstring 值文本 = .获取令牌值();
        double 数字值 = 0.0;
        try {
            数字值 = 编译数字.编译!(double)(值文本, 10);
        }
        catch(Throwable e) {
            数字值 = 0.0;
        }
        klang小数字面量_ 节点 = 创建节点!(klang小数字面量_)(KSK.小数字面量);
        节点.内容 = 值文本;
        节点.小数值 = 数字值;
        ··Klang节点_.Klang标识符_ 后缀标识符 = .尝试编译数字字面量后缀();
        if (后缀标识符 !is ··null!(··Klang节点_.Klang标识符_)) {
            dstring 内容 = 后缀标识符.标识符.内容;
            节点标志_ 后缀标志 = .获取小数字面量后缀(内容);
            if (后缀标志 != 节点标志_.无) {
                设置节点标志(节点, 后缀标志);
            }
            else {
                后缀错误 = true;
            }
            有后缀 = true;
        }
        else {
            设置节点标志(节点, 节点标志_.DF);
        }
        if (后缀错误) {
            .编译错误在(数字开始, .获取节点开始(), 诊断集_.编译错误_在_0_处, "后缀"d);
        }
        if (!有后缀) {
            .下个令牌();
        }
        return .完成节点!(klang小数字面量_)(节点, 数字开始);
    }
    dstring _0 = 编译器.获取令牌值();
    ulong 数字值2 = 0;
    if (_0 == "0"d) {
        return .尝试编译!(字面量类表达式基类_)(cast(字面量类表达式基类_ delegate())(·fd(&.可能是是十六进制或八进制或二进制数字)));
    }
    dstring 值文本 = 编译器.获取令牌值();
    try {
        数字值2 = 编译数字.编译!(ulong)(值文本, 10);
    }
    catch(Throwable _) {
        数字值2 = 0;
    }
    klang数字字面量_ 节点 = 创建节点!(klang数字字面量_)(KSK.数字字面量);
    节点.内容 = 值文本;
    节点.整数值 = 数字值2;
    ··Klang节点_.Klang标识符_ 整数后缀标识符 = .尝试编译数字字面量后缀();
    if (整数后缀标识符 !is ··null!(··Klang节点_.Klang标识符_)) {
        dstring 内容 = 整数后缀标识符.标识符.内容;
        节点标志_ 整数后缀标志 = .获取整数字面量后缀(内容);
        if (整数后缀标志 != 节点标志_.无) {
            设置节点标志(节点, 整数后缀标志);
        }
        else {
            节点标志_ 小数后缀标志 = .获取小数字面量后缀(内容);
            if (小数后缀标志 != 节点标志_.无) {
                klang小数字面量_ 转为小数字面量 = 创建节点!(klang小数字面量_)(KSK.小数字面量);
                转为小数字面量.开始 = 节点.开始;
                转为小数字面量.内容 = 值文本;
                转为小数字面量.小数值 = (cast(double)(数字值2));
                设置节点标志(转为小数字面量, 小数后缀标志);
                return .完成节点!(klang小数字面量_)(转为小数字面量, 数字开始);
            }
            后缀错误 = true;
        }
        有后缀 = true;
    }
    if (后缀错误) {
        .编译错误在(数字开始, .获取节点开始(), 诊断集_.编译错误_在_0_处, "后缀"d);
    }
    if (!有后缀) {
        .下个令牌();
    }
    return .完成节点!(klang数字字面量_)(节点, 数字开始);
}
字面量类表达式基类_ 扫描模板表达式(long 节点开始, long 起点, dstring 内容, bool 有转义字符, bool 有扩展转义字符) {
    long 开始 = 0;
    long 文本截取开始 = 0;
    long 跨度开始 = -1;
    KSK 模板种类 = KSK.模板头;
    模板中_[] 跨度数组 = [];
    Klang节点_ 表达式 = ··null!(Klang节点_);
    bool 是开始的反引号 = true;
    bool 刚刚完成模板头 = false;
    bool 是无替换的 = true;
    模板表达式_ 模板表达式 = 创建节点!(模板表达式_)(KSK.模板表达式);
    while(true) {
        dchar ch = (cast()(内容[开始]));
        if (ch == 字符_.反引 && 是开始的反引号) {
            是开始的反引号 = false;
            ++文本截取开始;
            ++开始;
            continue;
        }
        if (ch == 字符_.美元 && 内容[开始 + 1] == 字符_.左大括号) {
            是无替换的 = false;
            ++开始;
            KSK tok = 模板种类;
            if (tok == KSK.模板头) {
                模板头_ 模板头 = 创建节点!(模板头_)(KSK.模板头);
                dstring 模板头的内容 = 内容[文本截取开始 .. 开始 - 1];
                模板头.内容 = 编译器.初始文本值(模板头的内容);
                模板表达式.模板头 = .完成节点!(模板头_)(模板头, 节点开始, 起点 + 开始 + 1);
                模板种类 = KSK.模板中;
                刚刚完成模板头 = true;
                continue;
            }
            else {
                if (跨度开始 == -1) {
                    跨度开始 = 起点 + 开始;
                }
                dstring 上个中的内容 = 内容[文本截取开始 .. 开始 - 1];
                模板中_ 模板中 = 创建节点!(模板中_)(KSK.模板中);
                模板中.内容 = 编译器.初始文本值(上个中的内容);
                模板中.表达式 = 表达式;
                long 范围起点 = 起点 + 开始 + 1;
                .追加!(模板中_)(跨度数组, .完成节点!(模板中_)(模板中, 表达式.开始, 范围起点));
                size_t 文本长度 = 内容.length - 开始;
                long 下个开始 = 编译器.f·扫描范围!(long)(范围起点, 文本长度, () {
                    .下个令牌();
                    表达式 = .编译表达式();
                    return .获取令牌开始();
                });
                开始 += 下个开始 - 范围起点 + 1;
                文本截取开始 = 开始 + 1;
                continue;
            }
        }
        else if (刚刚完成模板头 && ch == 字符_.左大括号) {
            ++开始;
            if (跨度开始 == -1) {
                // 这里应该不可到达
                跨度开始 = 起点 + 开始;
            }
            long 范围起点 = 起点 + 开始;
            size_t 文本长度 = 内容.length - 开始;
            long 下个开始 = 编译器.f·扫描范围!(long)(范围起点, 文本长度, () {
                .下个令牌();
                表达式 = .编译表达式();
                return .获取令牌开始();
            });
            开始 += 下个开始 - 范围起点;
            文本截取开始 = 开始 + 1;
            刚刚完成模板头 = false;
            continue;
        }
        else if (ch == 字符_.反引) {
            if (是无替换的) {
                无替换模板字面量_ 无替换 = 创建节点!(无替换模板字面量_)(KSK.无替换模板字面量);
                dstring 缓存内容 = 编译器.初始文本值(内容);
                无替换.内容 = 缓存内容[1 .. $-1];
                无替换.原始文本 = 缓存内容;
                .下个令牌();
                return .完成文本类字面量后缀(无替换, 节点开始, false, 有转义字符, 有扩展转义字符);
            }
            else {
                基础节点.节点数组_!(模板中_) 模板中间组 = .创建节点数组!(模板中_)(跨度数组, 跨度开始, 表达式.开始);
                dstring 尾部文本 = 内容[文本截取开始 .. 开始];
                模板尾_ 尾 = 创建节点!(模板尾_)(KSK.模板尾);
                尾.内容 = 编译器.初始文本值(尾部文本);
                尾.表达式 = 表达式;
                模板表达式.模板跨度 = 模板中间组;
                模板表达式.模板尾 = .完成节点!(模板尾_)(尾, 表达式.开始, 起点 + 开始);
                break;
            }
        }
        else {
            ++开始;
        }
    }
    .下个令牌();
    return .完成文本类字面量后缀(模板表达式, 节点开始, false, 有转义字符, 有扩展转义字符);
}
字面量类表达式基类_ 完成文本类字面量后缀(字面量类表达式基类_ 文本类字面量, long 节点开始, bool 未完成的, bool 有转义, bool 有扩展转义) {
    if (!.有间隔() && .令牌() == KSK.标识符) {
        dstring 字符后缀 = .获取令牌值();
        节点标志_ 后缀 = .获取文本字面量类后缀(字符后缀);
        if (后缀 != 0) {
            文本类字面量.标志 |= (cast(整数_)(后缀));
            .下个令牌();
        }
    }
    if (未完成的) {
        .编译错误在(节点开始, .获取节点开始(), 诊断集_.编译错误_在_0_处, "字面量类表达式"d);
    }
    if (有转义) {
        设置节点标志(文本类字面量, 节点标志_.有转义);
    }
    if (有扩展转义) {
        设置节点标志(文本类字面量, 节点标志_.有扩展转义);
    }
    return .完成节点!(字面量类表达式基类_)(文本类字面量, 节点开始);
}
正则表达式字面量_ 编译正则表达式表达式() {
    节点标志_ delegate(dchar) 检查后缀;
    long 节点开始;
    long 令牌开始;
    bool 是未完成的;
    int 剪切开始;
    long 结束点;
    正则表达式字面量_ n;
    节点标志_ 检查后缀·func(dchar s) {
        switch (s) {
            case 字符_.d:
            case 字符_.D: {
                return 节点标志_.D;
            }
            case 字符_.w:
            case 字符_.W: {
                return 节点标志_.W;
            }
            case 字符_.c:
            case 字符_.C: {
                return 节点标志_.C;
            }
            case 字符_.g:
            case 字符_.G: {
                return 节点标志_.G;
            }
            case 字符_.i:
            case 字符_.I: {
                return 节点标志_.I;
            }
            case 字符_.m:
            case 字符_.M: {
                return 节点标志_.M;
            }
            case 字符_.s:
            case 字符_.S: {
                return 节点标志_.S;
            }
            case 字符_.x:
            case 字符_.X: {
                return 节点标志_.X;
            }
            default: {
                return 节点标志_.无;
            }
        }
    }
    检查后缀 = &检查后缀·func;
    节点开始 = .获取节点开始();
    令牌开始 = .获取令牌开始();
    是未完成的 = false;
    剪切开始 = 1;
    if (.令牌() == KSK.除等号) {
        剪切开始 = 2;
    }
    结束点 = .尝试编译!(long)(() {
        .下个令牌();
        bool 是转义 = false;
        bool 是在字符内 = false;
        while(true) {
            if (.前面有换行符() || .令牌() == KSK.文件结尾) {
                是未完成的 = true;
                break;
            }
            if (是转义) {
                是转义 = false;
            }
            else if (.令牌() == KSK.除号 && !是在字符内) {
                .下个令牌();
                break;
            }
            else if (.令牌() == KSK.左方括号) {
                是在字符内 = true;
            }
            else if (.令牌 == KSK.反斜杠) {
                是转义 = true;
            }
            else if (.令牌() == KSK.右方括号) {
                是在字符内 = false;
            }
            .下个令牌();
        }
        return .获取节点开始();
    });
    if (是未完成的) {
        .编译错误在(节点开始, 结束点, 诊断集_.自定义错误, "未完成的正则表达式"d);
    }
    n = 创建节点!(正则表达式字面量_)(KSK.正则表达式字面量);
    n.内容 = 编译器.初始文本值(源文件.内容[令牌开始 + 剪切开始 .. 结束点 - 1]);
    .·writeln(n.内容);
    if (.令牌() == KSK.标识符 && !.有间隔()) {
        long 后缀开始 = .获取节点开始();
        dstring 后缀 = .获取令牌值();
        if (后缀.length > 2) {
            .编译错误在(后缀开始, 后缀开始 + 后缀.length, 诊断集_.自定义错误, `正则表达式不支持的后缀`d ~ 后缀 ~ `.`d);
        }
        节点标志_ 后缀标志 = 节点标志_.无;
        {
            for (int i = 0; i < 后缀.length; ++i) {
                dchar ch = (cast()(后缀[i]));
                后缀标志 |= 检查后缀(ch);
            }
        }
        if ((后缀标志 & (节点标志_.W | 节点标志_.C | 节点标志_.D)) == 0) {
            后缀标志 |= 节点标志_.D;
        }
        if ((后缀标志 & (节点标志_.I | 节点标志_.M | 节点标志_.S | 节点标志_.X | 节点标志_.G)) == 0) {
            后缀标志 |= 节点标志_.G;
        }
        设置节点标志(n, 后缀标志);
        .下个令牌();
        return .完成节点!(正则表达式字面量_)(n, 节点开始);
    }
    return .完成节点!(正则表达式字面量_)(n, 节点开始, 结束点);
}
字面量类表达式基类_ 编译文本字面量表达式() {
    bool 有未完成的 = 编译器.是未完成的();
    bool 有转义字符 = 编译器.有转义字符();
    bool 有扩展转义字符 = 编译器.有扩展转义字符();
    long 文本开始 = .获取节点开始();
    assert(.令牌() == KSK.文本字面量, "'编译文本字面量表达式' 错误"c);
    dstring 引号类型 = 编译器.获取当前字面量引号();
    bool 出现了关注字符 = 编译器.是出现了关注字符();
    if (引号类型 == "\""d) {
        // "
        dstring 内容 = 编译器.初始文本值(.获取令牌值());
        klang文本字面量_ n = 创建节点!(klang文本字面量_)(KSK.文本字面量);
        n.内容 = 内容;
        .下个令牌();
        return .完成文本类字面量后缀(n, 文本开始, 有未完成的, 有转义字符, 有扩展转义字符);
    }
    else if (引号类型 == "'"d) {
        // '
        dstring 字符内容 = .获取令牌值();
        int 字符值 = 0;
        if (字符内容.length == 0) {
            字符值 = 0;
        }
        else if (字符内容.length > 1) {
            .编译错误在(文本开始, 文本开始 + 字符内容.length + 2, 诊断集_.编译错误_在_0_处, "字符字面量"d);
        }
        else {
            字符值 = (cast(ulong)(字符内容[0]));
        }
        字符字面量_ 字符字面量节点 = 创建节点!(字符字面量_)(KSK.字符字面量);
        字符字面量节点.内容 = 字符内容;
        字符字面量节点.字符值 = 字符值;
        .下个令牌();
        return .完成文本类字面量后缀(字符字面量节点, 文本开始, 有未完成的, 有转义字符, 有扩展转义字符);
    }
    else {
        // `
        assert(引号类型 == "`"d, "引号类型错误"c);
        if (出现了关注字符 && !有未完成的) {
            dstring 重扫内容 = 编译器.获取令牌文本();
            return .扫描模板表达式(.获取节点开始(), .获取令牌开始(), 重扫内容, 有转义字符, 有扩展转义字符);
        }
        else {
            无替换模板字面量_ 无替换字面量 = 创建节点!(无替换模板字面量_)(KSK.无替换模板字面量);
            无替换字面量.内容 = .获取令牌值();
            无替换字面量.原始文本 = 编译器.获取令牌文本();
            .下个令牌();
            return .完成文本类字面量后缀(无替换字面量, 文本开始, 有未完成的, 有转义字符, 有扩展转义字符);
        }
    }
}
bool 前面有换行符() {
    return 编译器.前面有换行符();
}
T 在上下文约束内编译(T)(节点标志_ 上下文, T delegate() 回调) {
    return 编译器.f·在上下文约束内编译!(T)((cast(整数_)(上下文)), cast(T delegate())(回调));
}
bool 是在上下文内(节点标志_ 标志) {
    return 编译器.是在上下文内((cast(整数_)(标志)));
}
void 设置标志(节点标志_ 标志) {
    编译器.设置当前标志(true, (cast(整数_)(标志)));
}
void 取消标志(节点标志_ 标志) {
    编译器.设置当前标志(false, (cast(整数_)(标志)));
}
bool 编译分号或逗号() {
    if (.令牌() == KSK.分号 || .令牌() == KSK.逗号) {
        .下个令牌();
        return true;
    }
    if (.可编译分号()) {
        return true;
    }
    else {
        if (!.编译可选的(KSK.逗号)) {
            return .编译确定的(KSK.分号);
        }
        return true;
    }
}
bool 编译分号() {
    if (.令牌() == KSK.分号) {
        .下个令牌();
        return true;
    }
    if (.可编译分号()) {
        return true;
    }
    return false;
}
逗号编译结果_ 编译逗号(bool delegate() 是结尾) {
    if (.令牌() == KSK.逗号) {
        .下个令牌();
        if (是结尾()) {
            return 逗号编译结果_.逗号后就结束_;
        }
        return 逗号编译结果_.是逗号_;
    }
    if (是结尾()) {
        return 逗号编译结果_.是结尾_;
    }
    .报告当前位置编译错误(.获取节点开始(), 1, 诊断集_.缺少必须的_0_令牌, ["逗号"d]);
    return 逗号编译结果_.错误_;
}
基础节点.节点数组_!(T) 编译列表(T)(编译上下文_ kind, T delegate() 编译元素) {
    long 储存编译上下文 = .编译上下文;
    .编译上下文 |= 1 << (cast(整数_)(kind));
    T[] 列表 = [];
    long 列表开始 = .获取节点开始();
    bool 有尾随逗号 = false;
    while(true) {
        if (.是列表元素(kind, /*是在报告错误*/ false)) {
            T 元素 = .编译列表元素!(T)(cast(T delegate())(编译元素));
            列表 = .追加!(T)(列表, (cast(T)(元素)));
            if (.是列表终结(kind)) {
                有尾随逗号 = 元素.后面是逗号;
                break;
            }
            continue;
        }
        if (.是列表终结(kind)) {
            break;
        }
        if (.中止分析列表或移动到下一个令牌(kind)) {
            break;
        }
    }
    .编译上下文 = 储存编译上下文;
    基础节点.节点数组_!(T) 结果 = .创建节点数组!(T)(列表, 列表开始);
    结果.有尾随逗号 = 有尾随逗号;
    return 结果;
}
// H
T 编译列表元素(T)(T delegate() 编译元素) {
    return 编译元素();
}
bool 中止分析列表或移动到下一个令牌(编译上下文_ kind) {
    .报告当前令牌编译错误(.编译上下文错误集_(kind));
    if (.是在相同的编译上下文()) {
        return true;
    }
    .下个令牌();
    return false;
}
bool 是列表终结(编译上下文_ kind) {
    if (.令牌() == KSK.文件结尾) {
        return true;
    }
    switch (kind) {
        case 编译上下文_.源码顶级语句_:
        case 编译上下文_.测试单元语句_: {
            return !(.是源码顶级语句开始() || .是程序集顶级语句());
        }
        case 编译上下文_.程序集顶级语句_: {
            return .令牌() == KSK.右大括号 || .令牌() == KSK.文件结尾;
        }
        case 编译上下文_.运算符签名列表: {
            return !.是运算符(.令牌());
        }
        case 编译上下文_.块语句组:
        case 编译上下文_.假如子句组:
        case 编译上下文_.枚举成员组:
        case 编译上下文_.接口字面量成员组:
        case 编译上下文_.结构对象字面量成员组:
        case 编译上下文_.词典字面量元素:
        case 编译上下文_.汉英词典元素_:
        case 编译上下文_.对象体成员_:
        case 编译上下文_.类型声明成员_:
        case 编译上下文_.接口声明成员_:
        case 编译上下文_.编译导入语句_:
        case 编译上下文_.编译导入从语句_: {
            return .令牌() == KSK.右大括号;
        }
        case 编译上下文_.假如子句语句组: {
            return .令牌() == KSK.右大括号 || .令牌() == KSK.若是_ || .令牌() == KSK.默认_;
        }
        case 编译上下文_.继承子句组元素: {
            return .令牌() == KSK.左大括号 || .令牌() == KSK.冒号;
        }
        case 编译上下文_.变量声明组: {
            return .是变量声明符列表终止符();
        }
        case 编译上下文_.类型形参组: {
            return .令牌() == KSK.右尖括号 || .令牌() == KSK.左括号 || .令牌() == KSK.左大括号 || .令牌() == KSK.冒号;
        }
        case 编译上下文_.实参表达式组: {
            return .令牌() == KSK.右括号 || .令牌() == KSK.分号;
        }
        case 编译上下文_.数组字面量成员组: {
            return .令牌() == KSK.右方括号 || .令牌() == KSK.右大括号;
        }
        case 编译上下文_.形参组: {
            return .令牌() == KSK.右括号 || .令牌() == KSK.右方括号 || .令牌() == KSK.冒等号;
        }
        case 编译上下文_.类型实参组: {
            return .令牌() == KSK.右尖括号;
        }
        case 编译上下文_.继承子句组: {
            return .令牌() == KSK.左大括号 || .令牌() == KSK.右大括号;
        }
        default: {
            return false;
        }
    }
}
bool 是列表元素(编译上下文_ 编译上下文, bool 是在错误恢复) {
    switch (编译上下文) {
        case 编译上下文_.源码顶级语句_:
        case 编译上下文_.测试单元语句_: {
            return !(.令牌() == KSK.冒号 && 是在错误恢复) && (.是源码顶级语句开始() || .是程序集顶级语句());
        }
        case 编译上下文_.编译导入语句_:
        case 编译上下文_.编译导入从语句_: {
            return .是标识符() || .令牌() == KSK.文本字面量 || .令牌() == KSK.公开_ || .令牌() == KSK.版本_;
        }
        case 编译上下文_.程序集顶级语句_: {
            return !(.令牌() == KSK.分号 && 是在错误恢复) && .是程序集顶级语句();
        }
        case 编译上下文_.块语句组:
        case 编译上下文_.假如子句语句组: {
            return !(.令牌() == KSK.分号 && 是在错误恢复) && .是语句的开始() && .令牌() != KSK.三点号;
        }
        case 编译上下文_.假如子句组: {
            return .令牌() == KSK.若是_ || .令牌() == KSK.默认_;
        }
        case 编译上下文_.对象体成员_: {
            return .向前看!(bool)(cast(bool delegate())(·fd(&.是类型成员开始)));
        }
        case 编译上下文_.类型声明成员_: {
            return .向前看!(bool)(cast(bool delegate())(·fd(&.是类型成员开始)));
        }
        case 编译上下文_.接口声明成员_: {
            return .向前看!(bool)(cast(bool delegate())(·fd(&.是类型声明成员开始)));
        }
        case 编译上下文_.枚举成员组: {
            return .令牌() == KSK.左大括号 || .是标识符();
        }
        case 编译上下文_.汉英词典元素_: {
            return .是标识符() || .令牌() == KSK.文本字面量;
        }
        case 编译上下文_.词典字面量元素: {
            switch (.令牌()) {
                case KSK.左大括号:
                case KSK.星号:
                case KSK.三点号:
                case KSK.点号: {
                    return true;
                }
                default: {
                    return .是表达式开始();
                }
            }
        }
        case 编译上下文_.接口字面量成员组: {
            return .是标识符() || .令牌() == KSK.三点号;
        }
        case 编译上下文_.结构对象字面量成员组: {
            return .是标识符() || .令牌() == KSK.三点号;
        }
        case 编译上下文_.继承子句组元素: {
            if (.令牌() == KSK.左大括号) {
                return .向前看!(bool)(cast(bool delegate())(·fd(&.是有效的继承子句对象字面量)));
            }
            if (!是在错误恢复) {
                return .是左侧表达式开始() && !.是继承子句扩展或实施();
            }
            else {
                return .是标识符() && !.是继承子句扩展或实施();
            }
        }
        case 编译上下文_.变量声明组:
        case 编译上下文_.类型形参组: {
            return .是标识符();
        }
        case 编译上下文_.数组字面量成员组: {
            switch (.令牌()) {
                case KSK.逗号:
                case KSK.点号: {
                    return true;
                }
                default: break;
            }
        }
        // falls through
        case 编译上下文_.实参表达式组: {
            return .是表达式开始();
        }
        case 编译上下文_.形参组: {
            return .是形参的开始();
        }
        case 编译上下文_.类型实参组: {
            return .令牌() == KSK.逗号 || .是类型的开始();
        }
        case 编译上下文_.运算符签名列表: {
            return .是运算符(.令牌());
        }
        case 编译上下文_.继承子句组: {
            return .是继承子句();
        }
        default: {
            break;
        }
    }
    assert(false, "Non-exhaustive case in '是列表元素'."c);
    return false;
}
bool 是在相同的编译上下文() {
    编译上下文_ k = 编译上下文_.源码顶级语句_;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.测试单元语句_;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.程序集顶级语句_;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.块语句组; // Statements in block
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.假如子句组; // Clauses in 假如 statement
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.假如子句语句组; // Statements in 假如 clause
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.枚举成员组; // Members in enum declaration
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.继承子句组元素; // Elements in a heritage clause
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.变量声明组; // Variable declarations in variable statement
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.实参表达式组; // Expressions in argument 列表
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.结构对象字面量成员组; // Members in object literal
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.接口字面量成员组;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.汉英词典元素_;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.词典字面量元素;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.数组字面量成员组; // Members in array literal
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.形参组; // 形参组 in parameter 列表
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.类型形参组; // Type parameters in type parameter 列表
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.类型实参组; // Type arguments in type argument 列表
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.继承子句组;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.对象体成员_;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.类型声明成员_;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.接口声明成员_;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.编译导入从语句_;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.编译导入语句_;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    k = 编译上下文_.运算符签名列表;
    if ((.编译上下文 & k) != 0 && (.是列表元素(k, /*是在报告错误*/ true) || .是列表终结(k))) {
        return true;
    }
    return false;
}
诊断消息_ 编译上下文错误集_(编译上下文_ 上下文) {
    switch (上下文) {
        case 编译上下文_.测试单元语句_: {
            return 诊断集_.不是测试单元语句;
        }
        case 编译上下文_.源码顶级语句_: {
            return 诊断集_.不是源码级顶级语句;
        }
        case 编译上下文_.程序集顶级语句_: {
            return 诊断集_.不是程序集级语句;
        }
        case 编译上下文_.块语句组: {
            return 诊断集_.Declaration_or_statement_expected;
        }
        case 编译上下文_.假如子句组: {
            return 诊断集_.case_or_default_expected;
        }
        case 编译上下文_.假如子句语句组: {
            return 诊断集_.Statement_expected;
        }
        case 编译上下文_.类型声明成员_: {
            return 诊断集_.不是类型声明的有效成员;
        }
        case 编译上下文_.接口声明成员_: {
            return 诊断集_.不是接口声明的有效成员;
        }
        case 编译上下文_.汉英词典元素_: {
            return 诊断集_.不是有效的转换词典成员;
        }
        case 编译上下文_.对象体成员_: {
            return 诊断集_.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
        }
        case 编译上下文_.枚举成员组: {
            return 诊断集_.Enum_member_expected;
        }
        case 编译上下文_.继承子句组元素: {
            return 诊断集_.Expression_expected;
        }
        case 编译上下文_.变量声明组: {
            return 诊断集_.Variable_declaration_expected;
        }
        case 编译上下文_.实参表达式组: {
            return 诊断集_.Argument_expression_expected;
        }
        case 编译上下文_.结构对象字面量成员组: {
            return 诊断集_.Property_assignment_expected;
        }
        case 编译上下文_.接口字面量成员组: {
            return 诊断集_.Property_assignment_expected;
        }
        case 编译上下文_.词典字面量元素: {
            return 诊断集_.Expression_or_comma_expected;
        }
        case 编译上下文_.数组字面量成员组: {
            return 诊断集_.Expression_or_comma_expected;
        }
        case 编译上下文_.形参组: {
            return 诊断集_.Parameter_declaration_expected;
        }
        case 编译上下文_.类型形参组: {
            return 诊断集_.Type_parameter_declaration_expected;
        }
        case 编译上下文_.类型实参组: {
            return 诊断集_.Type_argument_expected;
        }
        case 编译上下文_.继承子句组: {
            return 诊断集_.Unexpected_token_expected;
        }
        case 编译上下文_.编译导入从语句_: {
            return 诊断集_.意外导入成员;
        }
        case 编译上下文_.编译导入语句_: {
            return 诊断集_.意外导入成员;
        }
        case 编译上下文_.运算符签名列表: {
            return 诊断集_.意外的运算符;
        }
        default: {
            return ··null!(诊断消息_);
        }
    }
}
bool 是变量声明符列表终止符() {
    if (.可以编译分号()) {
        return true;
    }
    if (.令牌() == KSK.属于_) {
        return true;
    }
    if (.令牌() == KSK.等右尖号) {
        return true;
    }
    return false;
}
bool 可以编译分号() {
    if (.令牌() == KSK.分号) {
        return true;
    }
    return .令牌() == KSK.右大括号 || .令牌() == KSK.文件结尾 || .前面有换行符();
}
bool 是语句的开始() {
    switch (.令牌()) {
        case KSK.分号:
        case KSK.左大括号:
        case KSK.变量_:
        case KSK.共享_:
        case KSK.只读_:
        case KSK.恒定_:
        case KSK.静态_:
        case KSK.常量_:
        case KSK.如果_:
        case KSK.循环_:
        case KSK.继续_:
        case KSK.跳出_:
        case KSK.返回_:
        case KSK.假如_:
        case KSK.删除_:
        case KSK.调试_:
        case KSK.抛出_:
        case KSK.尝试_:
        case KSK.捕获_:
        case KSK.最后_:
        case KSK.延迟_:
        case KSK.版本_:
        case KSK.断言_:
        case KSK.同步_:
        case KSK.指令_:
        case KSK.测试_:
        case KSK.固定_:
        case KSK.私有_:
        case KSK.保护_:
        case KSK.重载_:
        case KSK.外部_:
        case KSK.声明_:
        case KSK.导出_: {
            return true;
        }
        default: {
            return .是表达式开始();
        }
    }
}
bool 是标识符() {
    if (.令牌() == KSK.美元) {
        return .向前看!(bool)(() { .下个令牌(); return .令牌() == KSK.文本字面量; });
    }
    if (.令牌() == KSK.标识符) {
        return true;
    }
    if (.令牌() == KSK.测试_) {
        return .是在上下文内(节点标志_.在版本验证上下文_);
    }
    return .令牌() >= KSK.第一个上下文关键字_;
}
bool 是二元运算符() {
    return .获取二元运算符优先级(.令牌()) > 0;
}
int 获取二元运算符优先级(KSK ksk) {
    switch (ksk) {
        case KSK.或或号: {
            return 5;
        }
        case KSK.且且号: {
            return 6;
        }
        case KSK.或号: {
            return 7;
        }
        case KSK.异或号: {
            return 8;
        }
        case KSK.且号: {
            return 9;
        }
        case KSK.等等号:
        case KSK.叹等号: {
            return 10;
        }
        case KSK.左尖括号:
        case KSK.右尖括号:
        case KSK.左尖等号:
        case KSK.右尖等号: {
            return 11;
        }
        case KSK.左左尖号:
        case KSK.右右尖号:
        case KSK.右右右尖号: {
            return 12;
        }
        case KSK.加号:
        case KSK.减号:
        case KSK.波折号: {
            return 13;
        }
        case KSK.星号:
        case KSK.除号:
        case KSK.百分号: {
            return 14;
        }
        default: {
            return -1;
        }
    }
}
bool 是表达式开始() {
    if (.是左侧表达式开始()) {
        return true;
    }
    switch (.令牌()) {
        case KSK.加号:
        case KSK.减号:
        case KSK.波折号:
        case KSK.叹号:
        case KSK.左尖括号:
        case KSK.三点号:
        case KSK.除号:
        case KSK.除等号:
        case KSK.新建_:
        case KSK.零值_:
        case KSK.空址_:
        case KSK.空值_:
        case KSK.真_:
        case KSK.假_:
        case KSK.数字字面量:
        case KSK.文本字面量:
        case KSK.不及_: {
            return true;
        }
        default: {
            if (.是二元运算符()) {
                return true;
            }
            return .是标识符();
        }
    }
}
bool 是左侧表达式开始() {
    switch (.令牌()) {
        case KSK.本体_:
        case KSK.基类_:
        case KSK.原型_:
        case KSK.零值_:
        case KSK.空址_:
        case KSK.空值_:
        case KSK.真_:
        case KSK.假_:
        case KSK.数字字面量:
        case KSK.文本字面量:
        case KSK.除号:
        case KSK.除等号:
        case KSK.对象_:
        case KSK.结构_:
        case KSK.新建_:
        case KSK.左括号:
        case KSK.左方括号:
        case KSK.左大括号:
        case KSK.函数_:
        case KSK.标识符:
        case KSK.汇编_:
        case KSK.点左括号:
        case KSK.共享_:
        case KSK.只读_:
        case KSK.恒定_: {
            return true;
        }
        default: {
            return .是标识符();
        }
    }
}
bool 可编译分号() {
    if (.令牌() == KSK.分号) {
        return true;
    }
    return .令牌() == KSK.右大括号 || .结尾令牌 != KSK.未知__ && .令牌() == .结尾令牌 || .令牌() == KSK.文件结尾 || .前面有换行符();
}
bool 可编译逗号() {
    if (.令牌() == KSK.逗号) {
        return true;
    }
    return .令牌() == KSK.右大括号 || .结尾令牌 != KSK.未知__ && .令牌() == .结尾令牌 || .令牌() == KSK.文件结尾 || .前面有换行符();
}
bool 是修饰符种类(KSK ksk) {
    switch (ksk) {
        case KSK.私有_:
        case KSK.保护_:
        case KSK.重载_:
        case KSK.只读_:
        case KSK.恒定_:
        case KSK.共享_:
        case KSK.静态_:
        case KSK.引用_:
        case KSK.局部_:
        case KSK.固定_:
        case KSK.返回_:
        case KSK.导出_:
        case KSK.返回局部引用_:
        case KSK.返回引用_:
        case KSK.局部引用_:
        case KSK.返回局部_:
        case KSK.纯净_:
        case KSK.安全_:
        case KSK.信任_:
        case KSK.系统_:
        case KSK.无回收_:
        case KSK.不抛出_: {
            return true;
        }
        default: break;
    }
    return false;
}
bool 是类型成员开始() {
    if (.令牌() == KSK.左括号 || .令牌() == KSK.星号 || .令牌() == KSK.左尖括号) {
        return true;
    }
    bool 是id令牌 = false;
    while(.是修饰符种类(.令牌())) {
        是id令牌 = true;
        .下个令牌();
    }
    if (是id令牌 && .令牌() == KSK.左大括号) {
        .下个令牌();
        return .是类型成员开始();
    }
    if (.令牌() == KSK.左方括号) {
        return true;
    }
    if (.是标识符()) {
        是id令牌 = true;
        .下个令牌();
    }
    if (是id令牌) {
        return .令牌() == KSK.左括号 || .令牌() == KSK.左尖括号 || .令牌() == KSK.问号 || .令牌() == KSK.冒号 || .令牌() == KSK.逗号 || .可编译分号();
    }
    return false;
}
bool 是类型声明成员开始() {
    bool 是id令牌 = false;
    while(.是修饰符种类(.令牌())) {
        是id令牌 = true;
        .下个令牌();
    }
    if (是id令牌 && .令牌() == KSK.左大括号) {
        .下个令牌();
        return .是类型声明成员开始();
    }
    if (.是标识符()) {
        是id令牌 = true;
        .下个令牌();
    }
    if (是id令牌) {
        return .令牌() == KSK.左括号 || .令牌() == KSK.左尖括号 || .令牌() == KSK.问号 || .令牌() == KSK.冒号 || .令牌() == KSK.逗号 || .可编译分号();
    }
    return false;
}
bool 是有效的继承子句对象字面量() {
    if (.下个令牌() == KSK.右大括号) {
        KSK 下个 = .下个令牌();
        return 下个 == KSK.逗号 || 下个 == KSK.左括号 || 下个 == KSK.冒号;
    }
    return true;
}
bool 下个令牌是表达式开始() {
    .下个令牌();
    return .是表达式开始();
}
bool 是继承子句扩展或实施() {
    if (.令牌() == KSK.冒号) {
        return .向前看!(bool)(cast(bool delegate())(·fd(&.下个令牌是表达式开始)));
    }
    return false;
}
bool 下个令牌是类型的开始() {
    .下个令牌();
    return .是类型的开始();
}
bool 下个令牌是数值字面量() {
    .下个令牌();
    return .令牌() == KSK.数字字面量;
}
bool 是括号或函数类型的开始() {
    .下个令牌();
    return .令牌() == KSK.右括号 || .是形参的开始();
}
bool 是类型的开始() {
    switch (.令牌()) {
        case KSK.通用_:
        case KSK.文本_:
        case KSK.文本8_:
        case KSK.文本16_:
        case KSK.文本32_:
        case KSK.真假_:
        case KSK.无值_:
        case KSK.空值_:
        case KSK.本体_:
        case KSK.左方括号:
        case KSK.左尖括号:
        case KSK.或号:
        case KSK.文本字面量:
        case KSK.数字字面量:
        case KSK.真_:
        case KSK.假_:
        case KSK.三点号:
        case KSK.正量_:
        case KSK.整数_:
        case KSK.小数_:
        case KSK.正整数_:
        case KSK.整数8_:
        case KSK.整数16_:
        case KSK.整数32_:
        case KSK.整数64_:
        case KSK.正整数8_:
        case KSK.正整数16_:
        case KSK.正整数32_:
        case KSK.正整数64_:
        case KSK.小数32_:
        case KSK.小数64_:
        case KSK.虚数32_:
        case KSK.虚数64_:
        case KSK.复数64_:
        case KSK.复数128_:
        case KSK.字符_:
        case KSK.字符8_:
        case KSK.字符16_:
        case KSK.字符32_:
        case KSK.字节_: {
            return true;
        }
        case KSK.恒定_:
        case KSK.只读_:
        case KSK.共享_: {
            return .向前看!(bool)(cast(bool delegate())(·fd(&.下个令牌是类型的开始)));
        }
        case KSK.对象_:
        case KSK.结构_: {
            return .开始编译约束类型 || .向前看!(bool)(cast(bool delegate())(·fd(&.下个令牌是类型的开始)));
        }
        case KSK.指针_:
        case KSK.函数_: {
            return .开始编译约束类型;
        }
        case KSK.减号: {
            return .向前看!(bool)(cast(bool delegate())(·fd(&.下个令牌是数值字面量)));
        }
        case KSK.左括号: {
            // Only consider '(' the 节点开始 of a type 如果 followed by ')', '...', an identifier, a modifier,
            // or something that starts a type. We don't want to consider things like '(1)' a type.
            return .向前看!(bool)(cast(bool delegate())(·fd(&.是括号或函数类型的开始)));
        }
        default: {
            return .是标识符();
        }
    }
}
bool 是形参的开始(bool 严格 = false) {
    if (.是标识符()) {
        if (!严格) {
            return true;
        }
        return .向前看!(bool)(() {
            .下个令牌();
            if (.令牌() == KSK.问号) {
                .下个令牌();
            }
            return .令牌() == KSK.冒号;
        });
    }
    KSK ksk = .令牌();
    if (ksk == KSK.公开_ || ksk == KSK.私有_ || ksk == KSK.保护_ || ksk == KSK.返回_ || ksk == KSK.引用_ || ksk == KSK.局部_ || ksk == KSK.返回局部引用_ || ksk == KSK.返回引用_ || ksk == KSK.局部引用_ || ksk == KSK.返回局部_) {
        if (!严格) {
            return true;
        }
        return .向前看!(bool)(() {
            .下个令牌();
            return .是形参的开始(严格);
        });
    }
    return false;
}
bool 是源码顶级语句开始() {
    switch (.令牌()) {
        case KSK.导入_:
        case KSK.程序_:
        case KSK.版本_:
        case KSK.指令_: {
            return true;
        }
        default: {
            return false;
        }
    }
}
bool 是程序集顶级语句() {
    switch (.令牌()) {
        case KSK.版本_:
        case KSK.否则_:
        case KSK.类型_:
        case KSK.变量_:
        case KSK.共享_:
        case KSK.常量_:
        case KSK.函数_:
        case KSK.启动_:
        case KSK.初始_:
        case KSK.枚举_:
        case KSK.接口_:
        case KSK.对象_:
        case KSK.结构_:
        case KSK.别名_:
        case KSK.测试_:
        case KSK.断言_:
        case KSK.指令_:
        case KSK.只读_:
        case KSK.恒定_:
        case KSK.局部_:
        case KSK.固定_:
        case KSK.外部_:
        case KSK.声明_:
        case KSK.导出_:
        case KSK.私有_:
        case KSK.保护_:
        case KSK.静态_:
        case KSK.纯净_:
        case KSK.安全_:
        case KSK.信任_:
        case KSK.系统_:
        case KSK.无回收_:
        case KSK.不抛出_: {
            return true;
        }
        default: {
            return false;
        }
    }
}
bool 是运算符(KSK tok) {
    return tok >= KSK.左尖括号 && tok <= KSK.或或号 || tok >= KSK.等号 && tok <= KSK.异或等号;
}
基础节点.节点数组_!(Klang节点_) 编译源文件平台() {
    return .编译列表!(Klang节点_)(编译上下文_.源码顶级语句_, cast(Klang节点_ delegate())(·fd(&.编译源码顶级语句)));
}
Klang节点_ 编译源码顶级语句() {
    switch (.令牌()) {
        case KSK.导入_: {
            return .编译导入声明或导入从声明();
        }
        case KSK.版本_: {
            return .编译源码级版本语句();
        }
        case KSK.指令_: {
            return .编译指令语句();
        }
        default: {
            if (.是在上下文内(节点标志_.在测试单元上下文_) || .是在上下文内(节点标志_.在版本验证上下文_)) {
                return .编译程序集顶级语句();
            }
            return .编译程序声明();
        }
    }
}
程序声明_ 编译程序声明() {
    long 节点开始 = .获取节点开始();
    程序声明_ n = 创建节点!(程序声明_)(KSK.程序声明);
    if (.编译可选的(KSK.程序_)) {
        if (.令牌() == KSK.启动_) {
            n.是启动声明 = true;
            源文件.是启动文件 = true;
        }
        n.名称 = .编译标识符();
    }
    bool 有括号 = .编译可选的(KSK.左大括号);
    n.语句组 = .编译列表!(Klang节点_)(编译上下文_.程序集顶级语句_, cast(Klang节点_ delegate())(·fd(&.编译程序集顶级语句)));
    if (有括号) {
        基础节点.令牌_!(SK) tok = .编译令牌节点!(基础节点.令牌_!(SK))();
        if (tok.种类 != SK.右大括号) {
            .编译错误在(tok.开始, tok.结束, 诊断集_.Examples_Colon_0, "}"d);
        }
        if ((tok.jsDoc !is null) && (tok.jsDoc.原型 !is ··null!(基础节点.节点_[]))) {
            基础节点.节点_ doc = 查找!(基础节点.节点_)(tok.jsDoc, (基础节点.节点_ doc) { return (doc.标志 & 节点标志_.dlang块_) != 0; });
            if (doc !is ··null!(基础节点.节点_)) {
                设置节点标志(.源文件, 节点标志_.dlang块_);
                设置节点标志(tok, 节点标志_.dlang块_);
            }
        }
        n.结尾令牌 = tok;
    }
    if (n.名称 is ··null!(··Klang节点_.Klang标识符_)) {
        if (.已有启动声明) {
            n.是启动声明 = true;
            源文件.是启动文件 = true;
        }
        else {
            路径模块.路径和路径片段_ 路径片段 = 正规化路径和片段(获取目录路径(源文件.文件名));
            dstring 目录名 = 路径片段.片段[路径片段.片段.length - 1];
            if (目录名 == "源码"d) {
                n.是启动声明 = true;
                源文件.是启动文件 = true;
            }
        }
    }
    return .完成节点!(程序声明_)(n, 节点开始);
}
bool 是导入从声明语句() {
    return .向前看!(bool)(cast(bool delegate())(·fd(&.前面是文本字面量)));
}
bool 前面是文本字面量() {
    return .令牌() == KSK.文本字面量;
}
导入声明基类_ 编译导入声明或导入从声明() {
    long 开始 = .获取节点开始();
    .编译确定的(KSK.导入_);
    if (.编译可选的(KSK.左大括号)) {
        导入声明_ n = 创建节点!(导入声明_)(KSK.导入声明);
        n.导入组 = .编译列表!(导入成员基类_)(编译上下文_.编译导入语句_, cast(导入成员基类_ delegate())(·fd(&.编译导入成员)));
        .编译确定的(KSK.右大括号);
        return .完成节点!(导入声明_)(n, 开始);
    }
    else {
        导入从声明_ n = 创建节点!(导入从声明_)(KSK.导入从声明);
        if (.令牌() == KSK.文本字面量) {
            n.模块名 = .编译文本字面量();
        }
        else {
            .编译错误在(开始, .获取节点开始(), 诊断集_.自定义错误, "导入模块名必须是一个有效路径."d);
        }
        .编译确定的(KSK.左大括号);
        n.导入组 = .编译列表!(导入从成员基类_)(编译上下文_.编译导入从语句_, cast(导入从成员基类_ delegate())(·fd(&.编译导入从成员)));
        .编译确定的(KSK.右大括号);
        return .完成节点!(导入从声明_)(n, 开始);
    }
}
导入成员基类_ 编译导入成员() {
    导入版本成员_ delegate() 编译导入版本成员;
    long 节点开始;
    导入成员_ n;
    bool 是公开的;
    导入版本成员_ 编译导入版本成员·func() {
        导入版本成员_ n;
        n = 创建节点!(导入版本成员_)(KSK.导入版本成员);
        .编译确定的(KSK.版本_);
        .编译确定的(KSK.左括号);
        n.表达式 = .编译表达式();
        .编译确定的(KSK.右括号);
        n.然后语句 = .编译导入成员版本语句块();
        n.然后语句.版本容器块种类 = .是版本另如容器块 ? 版本容器块种类_.是版本另如容器块_ : 版本容器块种类_.是版本容器块_;
        .是版本另如容器块 = false;
        if (.编译可选的(KSK.否则_)) {
            if (.令牌() == KSK.版本_) {
                .是版本另如容器块 = true;
                n.否则语句 = .编译导入成员();
            }
            else {
                n.否则语句 = .编译导入成员版本语句块();
                (cast(导入成员块_)(n.否则语句)).版本容器块种类 = 版本容器块种类_.是版本否则容器块_;
            }
        }
        return .完成节点!(导入版本成员_)(n, 节点开始);
    }
    编译导入版本成员 = &编译导入版本成员·func;
    节点开始 = .获取节点开始();
    if (.令牌() == KSK.版本_) {
        return .在上下文约束内编译!(导入版本成员_)(节点标志_.在版本验证上下文_, cast(导入版本成员_ delegate())(编译导入版本成员));
    }
    n = 创建节点!(导入成员_)(KSK.导入成员);
    是公开的 = false;
    if (.令牌() == KSK.公开_) {
        long 公开的开始 = .获取节点开始();
        是公开的 = true;
        .下个令牌();
        long 公开的结束 = .获取节点开始();
        if (编译器.是在上下文内((cast(整数_)(节点标志_.在测试单元上下文_)))) {
            .编译错误在(公开的开始, 公开的结束, 诊断集_.测试单元不能公开导入);
        }
    }
    if (.令牌() != KSK.文本字面量) {
        n.另命名名称 = .编译标识符();
        .编译确定的(KSK.冒号);
    }
    if (.令牌() == KSK.文本字面量) {
        n.模块名 = .编译文本字面量();
    }
    else {
        .编译错误在(节点开始, .获取节点开始(), 诊断集_.自定义错误, "导入模块名必须是一个有效路径."d);
    }
    if (n.模块名.内容 is ··null!(dstring)) {
        .编译错误在(n.模块名.开始, n.模块名.结束, 诊断集_.模块名不能为空);
    }
    n.是公开的 = 是公开的;
    .编译分号或逗号();
    return .完成节点!(导入成员_)(n, 节点开始);
}
导入成员块_ 编译导入成员版本语句块() {
    long 节点开始 = .获取节点开始();
    导入成员块_ n = 创建节点!(导入成员块_)(KSK.导入成员块);
    if (.编译确定的(KSK.左大括号)) {
        if (.前面有换行符()) {
            n.多行 = true;
        }
        n.语句组 = .编译列表!(导入成员基类_)(编译上下文_.编译导入语句_, cast(导入成员基类_ delegate())(·fd(&.编译导入成员)));
        .编译确定的(KSK.右大括号);
    }
    return .完成节点!(导入成员块_)(n, 节点开始);
}
导入从成员基类_ 编译导入从成员() {
    导入从版本成员_ delegate() 编译导入从版本成员;
    long 节点开始;
    导入从成员_ n;
    ··Klang节点_.Klang标识符_ 名称;
    ··Klang节点_.Klang标识符_ 另命名名称;
    导入从版本成员_ 编译导入从版本成员·func() {
        导入从版本成员_ n;
        n = 创建节点!(导入从版本成员_)(KSK.导入从版本成员);
        .编译确定的(KSK.版本_);
        .编译确定的(KSK.左括号);
        n.表达式 = .编译表达式();
        .编译确定的(KSK.右括号);
        n.然后语句 = .编译导入从成员版本语句块();
        n.然后语句.版本容器块种类 = .是版本另如容器块 ? 版本容器块种类_.是版本另如容器块_ : 版本容器块种类_.是版本容器块_;
        .是版本另如容器块 = false;
        if (.编译可选的(KSK.否则_)) {
            if (.令牌() == KSK.版本_) {
                .是版本另如容器块 = true;
                n.否则语句 = .编译导入从成员();
            }
            else {
                n.否则语句 = .编译导入从成员版本语句块();
                (cast(导入从成员块_)(n.否则语句)).版本容器块种类 = 版本容器块种类_.是版本否则容器块_;
            }
        }
        return .完成节点!(导入从版本成员_)(n, 节点开始);
    }
    编译导入从版本成员 = &编译导入从版本成员·func;
    节点开始 = .获取节点开始();
    if (.令牌() == KSK.版本_) {
        return .在上下文约束内编译!(导入从版本成员_)(节点标志_.在版本验证上下文_, cast(导入从版本成员_ delegate())(编译导入从版本成员));
    }
    n = 创建节点!(导入从成员_)(KSK.导入从成员);
    名称 = .编译标识符();
    另命名名称 = ··null!(··Klang节点_.Klang标识符_);
    if (.编译可选的(KSK.冒号)) {
        另命名名称 = 名称;
        名称 = .编译标识符();
    }
    n.名称 = 名称;
    n.另命名名称 = 另命名名称;
    .编译分号或逗号();
    return .完成节点!(导入从成员_)(n, 节点开始);
}
导入从成员块_ 编译导入从成员版本语句块() {
    long 节点开始 = .获取节点开始();
    导入从成员块_ n = 创建节点!(导入从成员块_)(KSK.导入从成员块);
    if (.编译确定的(KSK.左大括号)) {
        if (.前面有换行符()) {
            n.多行 = true;
        }
        n.语句组 = .编译列表!(导入从成员基类_)(编译上下文_.编译导入从语句_, cast(导入从成员基类_ delegate())(·fd(&.编译导入从成员)));
        .编译确定的(KSK.右大括号);
    }
    return .完成节点!(导入从成员块_)(n, 节点开始);
}
源码级版本语句_ 编译源码级版本语句() {
    源码级版本语句_ delegate() 源码版本语句;
    long 节点开始;
    源码级版本语句_ 源码版本语句·func() {
        .编译确定的(KSK.版本_);
        if (.编译可选的(KSK.等号)) {
            版本表达式语句_ n = 创建节点!(版本表达式语句_)(KSK.版本表达式语句);
            n.表达式 = .编译标识符();
            dstring id = 核心.文本转大写(n.表达式.标识符.内容);
            if (!文件设置的版本标识符.具有(id)) {
                文件设置的版本标识符.p·设置(id, id);
            }
            if (.是在上下文内(节点标志_.在测试单元上下文_)) {
                .编译错误在(n.开始, n.表达式.结束, 诊断集_.版本声明不能位于_语句级版本_块内);
            }
            .完成节点!(版本表达式语句_)(n, 节点开始);
            .编译分号();
            return (cast(源码级版本语句_)(n));
        }
        else {
            版本语句_ n = 创建节点!(版本语句_)(KSK.版本语句);
            n.是顶级的 = true;
            .编译确定的(KSK.左括号);
            n.表达式 = .编译表达式();
            if (.是在上下文内(节点标志_.在测试单元上下文_)) {
                .编译错误在(n.开始, n.表达式.结束, 诊断集_.版本声明不能位于_语句级版本_块内);
            }
            .编译确定的(KSK.右括号);
            n.然后语句 = .编译版本语句块(true);
            n.然后语句.版本容器块种类 = .是版本另如容器块 ? 版本容器块种类_.是版本另如容器块_ : 版本容器块种类_.是版本容器块_;
            .是版本另如容器块 = false;
            if (.编译可选的(KSK.否则_)) {
                if (.令牌() == KSK.版本_) {
                    .是版本另如容器块 = true;
                    n.否则语句 = .编译源码顶级语句();
                }
                else {
                    n.否则语句 = .编译版本语句块(true);
                    (cast(块_)(n.否则语句)).版本容器块种类 = 版本容器块种类_.是版本否则容器块_;
                }
            }
            return (cast(源码级版本语句_)(.完成节点!(版本语句_)(n, 节点开始)));
        }
    }
    源码版本语句 = &源码版本语句·func;
    节点开始 = .获取节点开始();
    return .在上下文约束内编译!(源码级版本语句_)(节点标志_.在版本验证上下文_, cast(源码级版本语句_ delegate())(源码版本语句));
}
块_ 编译版本语句块(bool 在顶级 = false) {
    long 节点开始 = .获取节点开始();
    块_ n = 创建节点!(块_)(KSK.块);
    .编译确定的(KSK.左大括号);
    n.语句组 = .编译列表!(Klang节点_)(在顶级 ? 编译上下文_.源码顶级语句_ : 编译上下文_.块语句组, 在顶级 ? cast(Klang节点_ delegate())(·fd(&.编译源码顶级语句)) : cast(Klang节点_ delegate())(·fd(&.编译语句)));
    .编译确定的(KSK.右大括号);
    return .完成节点!(块_)(n, 节点开始);
}
指令语句_ 编译指令语句() {
    long 节点开始 = .获取节点开始();
    指令语句_ n = 创建节点!(指令语句_)(KSK.指令语句);
    .编译确定的(KSK.指令_);
    bool 有括号 = .编译可选的(KSK.左括号);
    bool 有参数 = .令牌() != KSK.标识符;
    if (.令牌() == KSK.标识符) {
        n.名称 = .编译标识符();
        有参数 = .编译可选的(KSK.逗号);
    }
    if (有参数) {
        if (.令牌() == KSK.文本字面量) {
            n.参数 = .编译文本字面量();
        }
        else {
            .编译错误在(节点开始, .获取节点开始(), 诊断集_.自定义错误, "指令语句的参数只能是标识符或一个文本字面量表达式."d);
        }
    }
    // 必须是 第一个语句.
    if ((n.名称 !is ··null!(··Klang节点_.Klang标识符_)) && (n.名称.标识符.内容 == "dlang"d || n.名称.标识符.内容 == "D语言"d)) {
        if (!.是在上下文内(节点标志_.Ambient)) {
            .编译错误在(n.开始, .获取节点开始(), 诊断集_.dlang环境指令只能在声明文件中使用);
        }
        .设置标志(节点标志_.dlangAmbient);
        n.标志 |= (cast(整数_)(节点标志_.dlangAmbient));
    }
    if (有括号) {
        .编译确定的(KSK.右括号);
    }
    .编译分号();
    return .完成节点!(指令语句_)(n, 节点开始);
}
Klang节点_ 转为语句(Klang节点_ n) {
    return (cast(语句_)(n));
}
Klang节点_ 编译程序集顶级语句() {
    switch (.令牌()) {
        case KSK.变量_:
        case KSK.常量_: {
            return .编译变量声明语句(true);
        }
        case KSK.函数_: {
            return .转为语句(.编译函数声明());
        }
        case KSK.对象_: {
            return .转为语句(.编译对象声明());
        }
        case KSK.结构_: {
            return .转为语句(.编译结构声明());
        }
        case KSK.接口_: {
            return .转为语句(.编译接口声明());
        }
        case KSK.枚举_: {
            return .转为语句(.编译枚举声明());
        }
        case KSK.类型_: {
            return .转为语句(.编译类型声明());
        }
        case KSK.别名_: {
            return .转为语句(.编译类型别名());
        }
        case KSK.初始_: {
            return .转为语句(.编译初始函数());
        }
        case KSK.启动_: {
            return .转为语句(.编译启动函数());
        }
        case KSK.指令_: {
            return .编译指令语句();
        }
        case KSK.测试_: {
            return .编译测试单元语句();
        }
        case KSK.断言_: {
            return .编译断言语句();
        }
        case KSK.版本_: {
            return .编译版本语句(true);
        }
        case KSK.只读_:
        case KSK.共享_:
        case KSK.恒定_:
        case KSK.局部_:
        case KSK.静态_:
        case KSK.固定_:
        case KSK.导出_:
        case KSK.私有_:
        case KSK.保护_:
        case KSK.外部_:
        case KSK.声明_:
        case KSK.重载_: {
            if (.是声明的开始()) {
                return .编译声明();
            }
        }
        default: break;
    }
    throw new Throwable(·to!(string)(("允许不到这里"d)));
}
Klang节点_ 编译语句() {
    switch (.令牌()) {
        case KSK.变量_:
        case KSK.常量_:
        case KSK.静态_: {
            return .编译变量声明语句();
        }
        case KSK.函数_: {
            return .转为语句(.编译函数声明());
        }
        case KSK.分号: {
            return .编译空语句();
        }
        case KSK.左大括号: {
            return .编译块();
        }
        case KSK.如果_:
        case KSK.另如_: {
            return .编译如果语句(.令牌());
        }
        case KSK.循环_: {
            return .编译迭代类语句();
        }
        case KSK.继续_: {
            return .编译继续语句();
        }
        case KSK.跳出_: {
            return .编译跳出语句();
        }
        case KSK.删除_: {
            return .编译删除语句();
        }
        case KSK.延迟_: {
            return .编译延迟语句();
        }
        case KSK.指令_: {
            return .编译指令语句();
        }
        case KSK.版本_: {
            return .编译版本语句();
        }
        case KSK.返回_: {
            return .编译返回语句();
        }
        case KSK.假如_: {
            return .编译假如语句();
        }
        case KSK.抛出_: {
            return .编译抛出语句();
        }
        case KSK.断言_: {
            return .编译断言语句();
        }
        case KSK.同步_: {
            return .编译同步语句();
        }
        case KSK.尝试_:
        case KSK.捕获_:
        case KSK.最后_: {
            return .编译尝试语句();
        }
        case KSK.调试_: {
            return .编译调试语句();
        }
        case KSK.固定_:
        case KSK.私有_:
        case KSK.保护_:
        case KSK.重载_:
        case KSK.外部_:
        case KSK.声明_:
        case KSK.导出_: {
            long 节点开始 = .获取节点开始();
            .下个令牌();
            long 节点结束 = .获取节点开始();
            .编译错误在(节点开始, 节点结束, 诊断集_.Expression_expected);
            return .编译语句();
        }
        default: break;
    }
    return .编译表达式或标签语句();
}
空语句_ 编译空语句() {
    long 节点开始 = .获取节点开始();
    空语句_ n = 创建节点!(空语句_)(KSK.空语句);
    .编译确定的(KSK.分号);
    return .完成节点!(空语句_)(n, 节点开始);
}
如果语句_ 编译如果语句(KSK ksk) {
    long 节点开始 = .获取节点开始();
    如果语句_ n = 创建节点!(如果语句_)(KSK.如果语句);
    .编译确定的(ksk);
    .编译确定的(KSK.左括号);
    bool 储存 = .有静态表达式;
    n.表达式 = .编译表达式();
    if (.有静态表达式) {
        设置节点标志(n, 节点标志_.是静态的_);
    }
    .编译确定的(KSK.右括号);
    n.然后语句 = .编译语句();
    if (.编译可选的(KSK.否则_) || .令牌() == KSK.另如_) {
        n.否则语句 = .编译语句();
    }
    .有静态表达式 = 储存;
    return .完成节点!(如果语句_)(n, 节点开始);
}
Klang节点_ 编译迭代类语句() {
    long 节点开始 = .获取节点开始();
    .编译确定的(KSK.循环_);
    .编译确定的(KSK.左括号);
    迭代类语句_ 迭代语句;
    if (!.编译可选的(KSK.右括号)) {
        Klang节点_ 初始化;
        if (.令牌() != KSK.分号) {
            if (.令牌() == KSK.变量_ || .令牌() == KSK.常量_) {
                初始化 = .编译变量声明列表(/*在循环语句初始化*/ true);
                foreach (变量声明_ n; (cast(变量声明列表_)(初始化)).声明组) {
                    设置节点标志(n, 节点标志_.不检查初始化);
                }
            }
            else {
                初始化 = .编译表达式();
            }
        }
        if (.编译可选的(KSK.属于_)) {
            循环属于_ 循环属于 = 创建节点!(循环属于_)(KSK.循环属于);
            循环属于.初始化 = 初始化;
            设置节点标志(循环属于.初始化, 节点标志_.Let);
            循环属于.表达式 = .编译赋值表达式或更高();
            .编译确定的(KSK.右括号);
            迭代语句 = 循环属于;
        }
        else {
            if (.编译可选的(KSK.分号)) {
                循环语句_ 循环语句 = 创建节点!(循环语句_)(KSK.循环语句);
                循环语句.初始化 = 初始化;
                if (.令牌() != KSK.分号 && .令牌() != KSK.右括号) {
                    (循环语句).条件 = .编译表达式();
                }
                .编译确定的(KSK.分号);
                if (.令牌() != KSK.右括号) {
                    (循环语句).自增 = .编译表达式();
                }
                迭代语句 = 循环语句;
            }
            else {
                当循环语句_ 当循环语句 = 创建节点!(当循环语句_)(KSK.当循环语句);
                当循环语句.表达式 = 初始化;
                迭代语句 = 当循环语句;
            }
            .编译确定的(KSK.右括号);
        }
    }
    else {
        迭代语句 = 创建节点!(循环语句_)(KSK.循环语句);
    }
    迭代语句.语句 = .编译语句();
    return .完成节点!(迭代类语句_)(迭代语句, 节点开始);
}
bool 前方有属于关键字() {
    .下个令牌();
    while(.令牌() != KSK.文件结尾 && !.前面有换行符()) {
        if (.令牌() == KSK.属于_) {
            return true;
        }
        .下个令牌();
    }
    return false;
}
跳出语句_ 编译跳出语句() {
    long 节点开始 = .获取节点开始();
    跳出语句_ n = 创建节点!(跳出语句_)(KSK.跳出语句);
    .编译确定的(KSK.跳出_);
    if (!.可以编译分号()) {
        n.标签 = .编译标识符();
    }
    .编译分号();
    return .完成节点!(跳出语句_)(n, 节点开始);
}
继续语句_ 编译继续语句() {
    long 节点开始 = .获取节点开始();
    继续语句_ n = 创建节点!(继续语句_)(KSK.继续语句);
    .编译确定的(KSK.继续_);
    if (!.可以编译分号()) {
        n.标签 = .编译标识符();
    }
    .编译分号();
    return .完成节点!(继续语句_)(n, 节点开始);
}
延迟语句_ 编译延迟语句() {
    long 节点开始 = .获取节点开始();
    延迟语句_ n = 创建节点!(延迟语句_)(KSK.延迟语句);
    .编译确定的(KSK.延迟_);
    n.语句 = .编译语句();
    .编译分号();
    return .完成节点!(延迟语句_)(n, 节点开始);
}
删除语句_ 编译删除语句() {
    long 节点开始 = .获取节点开始();
    删除语句_ n = 创建节点!(删除语句_)(KSK.删除语句);
    .编译确定的(KSK.删除_);
    n.表达式 = .编译表达式();
    return .完成节点!(删除语句_)(n, 节点开始);
}
返回语句_ 编译返回语句() {
    long 节点开始 = .获取节点开始();
    返回语句_ n = 创建节点!(返回语句_)(KSK.返回语句);
    .编译确定的(KSK.返回_);
    if (!.可以编译分号()) {
        n.表达式 = .编译简洁变量初始化表达式();
        if (.正在编译构建声明) {
            .报告当前位置编译错误(n.表达式.开始, n.表达式.结束, 诊断集_.构建声明或释放声明禁止返回值, ["此语境禁止返回."d]);
        }
    }
    .编译分号();
    if (.有静态表达式 || .是在上下文内(节点标志_.在版本验证上下文_)) {
        设置节点标志(n, 节点标志_.是静态的_);
    }
    return .完成节点!(返回语句_)(n, 节点开始);
}
假如语句_ 编译假如语句() {
    基础节点.节点数组_!(若是或默认子句_) delegate() 内部编译;
    long 节点开始;
    假如语句_ n;
    bool 储存;
    long 若是块开始;
    若是块_ 若是块;
    基础节点.节点数组_!(若是或默认子句_) 内部编译·func() {
        return .编译列表!(若是或默认子句_)(编译上下文_.假如子句组, cast(若是或默认子句_ delegate())(·fd(&.编译若是或默认子句)));
    }
    内部编译 = &内部编译·func;
    节点开始 = .获取节点开始();
    n = 创建节点!(假如语句_)(KSK.假如语句);
    .编译确定的(KSK.假如_);
    .编译确定的(KSK.左括号);
    储存 = .有静态表达式;
    n.表达式 = .编译表达式();
    if (.有静态表达式) {
        设置节点标志(n, 节点标志_.是静态的_);
    }
    .编译确定的(KSK.右括号);
    若是块开始 = .获取节点开始();
    若是块 = 创建节点!(若是块_)(KSK.若是块);
    .编译确定的(KSK.左大括号);
    if (是类型查询表达式(n.表达式)) {
        若是块.子句组 = .在上下文约束内编译!(基础节点.节点数组_!(若是或默认子句_))(节点标志_.类型查询上下文_, cast(基础节点.节点数组_!(若是或默认子句_) delegate())(内部编译));
    }
    else {
        若是块.子句组 = 内部编译();
    }
    .编译确定的(KSK.右大括号);
    n.若是块 = .完成节点!(若是块_)(若是块, 若是块开始);
    .有静态表达式 = 储存;
    return .完成节点!(假如语句_)(n, 节点开始);
}
若是子句_ 编译若是子句() {
    long 节点开始 = .获取节点开始();
    若是子句_ n = 创建节点!(若是子句_)(KSK.若是子句);
    .编译确定的(KSK.若是_);
    n.表达式 = .是在上下文内(节点标志_.类型查询上下文_) ? .编译类型() : .编译表达式();
    .编译确定的(KSK.冒号);
    n.语句组 = .编译列表!(Klang节点_)(编译上下文_.假如子句语句组, cast(Klang节点_ delegate())(·fd(&.编译语句)));
    return .完成节点!(若是子句_)(n, 节点开始);
}
默认子句_ 编译默认子句() {
    long 节点开始 = .获取节点开始();
    默认子句_ n = 创建节点!(默认子句_)(KSK.默认子句);
    .编译确定的(KSK.默认_);
    .编译确定的(KSK.冒号);
    n.语句组 = .编译列表!(Klang节点_)(编译上下文_.假如子句语句组, cast(Klang节点_ delegate())(·fd(&.编译语句)));
    return .完成节点!(默认子句_)(n, 节点开始);
}
若是或默认子句_ 编译若是或默认子句() {
    return .令牌() == KSK.若是_ ? .编译若是子句() : .编译默认子句();
}
抛出语句_ 编译抛出语句() {
    long 节点开始 = .获取节点开始();
    抛出语句_ n = 创建节点!(抛出语句_)(KSK.抛出语句);
    .编译确定的(KSK.抛出_);
    if (!.前面有换行符()) {
        n.表达式 = .编译表达式();
    }
    .编译分号();
    if (.有静态表达式 || .是在上下文内(节点标志_.在版本验证上下文_)) {
        设置节点标志(n, 节点标志_.是静态的_);
    }
    return .完成节点!(抛出语句_)(n, 节点开始);
}
同步语句_ 编译同步语句() {
    long 节点开始 = .获取节点开始();
    同步语句_ n = 创建节点!(同步语句_)(KSK.同步语句);
    .编译确定的(KSK.同步_);
    if (.令牌() == KSK.左括号) {
        n.实参组 = .编译实参列表();
    }
    .编译确定的(KSK.左大括号);
    n.语句组 = .编译列表!(Klang节点_)(编译上下文_.块语句组, cast(Klang节点_ delegate())(·fd(&.编译语句)));
    .编译确定的(KSK.右大括号);
    return .完成节点!(同步语句_)(n, 节点开始);
}
尝试语句_ 编译尝试语句() {
    long 节点开始 = .获取节点开始();
    尝试语句_ n = 创建节点!(尝试语句_)(KSK.尝试语句);
    .编译确定的(KSK.尝试_);
    n.尝试块 = .编译块();
    if (.令牌() == KSK.捕获_) {
        n.捕获子句 = .编译捕获子句();
    }
    if ((n.捕获子句 is ··null!(捕获子句_)) || .令牌() == KSK.最后_) {
        .编译确定的(KSK.最后_);
        n.最后块 = .编译块();
    }
    return .完成节点!(尝试语句_)(n, 节点开始);
}
捕获子句_ 编译捕获子句() {
    long 节点开始 = .获取节点开始();
    捕获子句_ 结果 = 创建节点!(捕获子句_)(KSK.捕获子句);
    .编译确定的(KSK.捕获_);
    if (.编译可选的(KSK.左括号)) {
        结果.变量声明 = .编译变量声明();
        .编译确定的(KSK.右括号);
    }
    结果.块 = .编译块();
    return .完成节点!(捕获子句_)(结果, 节点开始);
}
调试语句_ 编译调试语句() {
    long 节点开始 = .获取节点开始();
    调试语句_ n = 创建节点!(调试语句_)(KSK.调试语句);
    .编译确定的(KSK.调试_);
    .编译分号();
    return .完成节点!(调试语句_)(n, 节点开始);
}
Klang节点_ 编译表达式或标签语句() {
    long 节点开始 = .获取节点开始();
    Klang节点_ 表达式 = .编译表达式();
    if (.编译可选的(KSK.冒号) && 是符号引用表达式(表达式)) {
        符号引用表达式_ 引用表达式 = 获取符号引用表达式(表达式);
        标签语句_ n = 创建节点!(标签语句_)(KSK.标签语句);
        n.标签 = 引用表达式.表达式;
        n.语句 = .编译语句();
        return .完成节点!(标签语句_)(n, 节点开始);
    }
    else {
        表达式语句_ n = 创建节点!(表达式语句_)(KSK.表达式语句);
        n.表达式 = 表达式;
        .编译分号();
        return .完成节点!(表达式语句_)(n, 节点开始);
    }
}
bool 是声明() {
    while(true) {
        switch (.令牌()) {
            case KSK.变量_:
            case KSK.常量_:
            case KSK.类型_:
            case KSK.别名_:
            case KSK.对象_:
            case KSK.结构_:
            case KSK.接口_:
            case KSK.函数_:
            case KSK.枚举_:
            case KSK.测试_:
            case KSK.版本_: {
                return true;
            }
            case KSK.共享_:
            case KSK.只读_:
            case KSK.恒定_:
            case KSK.局部_:
            case KSK.静态_:
            case KSK.固定_:
            case KSK.私有_:
            case KSK.保护_:
            case KSK.导出_:
            case KSK.重载_: {
                .下个令牌();
                if (.令牌() == KSK.左大括号) {
                    .下个令牌();
                    return .是声明();
                }
                if (.前面有换行符()) {
                    return false;
                }
                continue;
            }
            case KSK.外部_: {
                return .是外部修饰符();
            }
            default: {
                return false;
            }
        }
    }
}
bool 是外部修饰符() {
    if (.令牌() == KSK.外部_) {
        .下个令牌();
        if (.前面有换行符()) {
            return false;
        }
        if (.令牌() == KSK.左括号) {
            .下个令牌();
            while(!.前面有换行符()) {
                .下个令牌();
                if (.令牌() == KSK.右括号) {
                    .下个令牌();
                    break;
                }
            }
        }
        if (.令牌() == KSK.左大括号) {
            .下个令牌();
        }
        return .是声明();
    }
    return false;
}
bool 是声明的开始() {
    return .向前看!(bool)(cast(bool delegate())(·fd(&.是声明)));
}
Klang节点_ 编译声明() {
    .全局的节点开始位置 = .获取节点开始();
    .全局修饰符数组 = .编译修饰符组();
    编译器.储存当前标志();
    Klang节点_ n = .编译声明平台();
    编译器.恢复当前标志();
    .全局的节点开始位置 = 0;
    .全局修饰符数组 = ··null!(基础节点.节点数组_!(修饰符_));
    return n;
}
Klang节点_ 编译声明平台() {
    switch (.令牌()) {
        case KSK.左大括号: {
            return .编译声明块();
        }
        case KSK.变量_:
        case KSK.常量_: {
            return .编译变量声明语句(true);
        }
        case KSK.对象_: {
            return .转为语句(.编译对象声明());
        }
        case KSK.结构_: {
            return .转为语句(.编译结构声明());
        }
        case KSK.接口_: {
            return .转为语句(.编译接口声明());
        }
        case KSK.类型_: {
            return .转为语句(.编译类型声明());
        }
        case KSK.别名_: {
            return .转为语句(.编译类型别名());
        }
        case KSK.函数_: {
            return .转为语句(.编译函数声明());
        }
        case KSK.枚举_: {
            return .转为语句(.编译枚举声明());
        }
        case KSK.测试_: {
            return .编译测试单元语句();
        }
        case KSK.版本_: {
            return .编译版本语句(true);
        }
        default: {
            if ((.全局修饰符数组 !is null) && (.全局修饰符数组.原型 !is ··null!(修饰符_[]))) {
                失踪声明_ 失踪的 = .创建失踪klang节点!(失踪声明_)(KSK.失踪声明, /*报告错误在当前位置*/ true, 诊断集_.Declaration_expected);
                失踪的.修饰符 = .全局修饰符数组;
                .全局修饰符数组 = new 基础节点.节点数组_!(修饰符_)([]);
                Klang节点_ 失踪的语句 = .转为语句(.完成节点!(失踪声明_)(失踪的, .全局的节点开始位置));
                return 失踪的语句;
            }
        }
    }
    throw new Throwable(·to!(string)(("不及"d)));
}
块_ 编译声明块() {
    块_ n = 创建节点!(块_)(KSK.块);
    n.版本容器块种类 = 版本容器块种类_.是声明块_;
    n.修饰符 = .全局修饰符数组;
    .编译确定的(KSK.左大括号);
    n.语句组 = .编译列表!(Klang节点_)(编译上下文_.程序集顶级语句_, cast(Klang节点_ delegate())(·fd(&.编译程序集顶级语句)));
    .编译确定的(KSK.右大括号);
    return .完成节点!(块_)(n, .全局的节点开始位置);
}
断言语句_ 编译断言语句() {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    断言语句_ n = 创建节点!(断言语句_)(KSK.断言语句);
    n.修饰符 = .全局修饰符数组;
    .编译确定的(KSK.断言_);
    n.实参组 = .编译实参列表();
    .编译分号();
    return .完成节点!(断言语句_)(n, 节点开始);
}
源码级版本语句_ 编译版本语句(bool 在顶级 = false) {
    版本语句_ delegate() 编译;
    long 节点开始;
    版本语句_ 编译·func() {
        版本语句_ n;
        n = 创建节点!(版本语句_)(KSK.版本语句);
        n.修饰符 = .全局修饰符数组;
        n.是顶级的 = 在顶级;
        .编译确定的(KSK.左括号);
        n.表达式 = .编译表达式();
        .编译确定的(KSK.右括号);
        n.然后语句 = .编译版本语句块(在顶级);
        n.然后语句.版本容器块种类 = .是版本另如容器块 ? 版本容器块种类_.是版本另如容器块_ : 版本容器块种类_.是版本容器块_;
        .是版本另如容器块 = false;
        if (.编译可选的(KSK.否则_)) {
            if (.令牌() == KSK.版本_) {
                .是版本另如容器块 = true;
                n.否则语句 = 在顶级 ? .编译程序集顶级语句() : .编译语句();
            }
            else {
                n.否则语句 = .编译版本语句块(在顶级);
                (cast(块_)((cast(语句_)(n.否则语句)))).版本容器块种类 = 版本容器块种类_.是版本否则容器块_;
            }
        }
        return .完成节点!(版本语句_)(n, 节点开始);
    }
    编译 = &编译·func;
    节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    .编译确定的(KSK.版本_);
    if (.编译可选的(KSK.等号)) {
        版本表达式语句_ n = 创建节点!(版本表达式语句_)(KSK.版本表达式语句);
        n.修饰符 = .全局修饰符数组;
        n.表达式 = .编译标识符();
        dstring id = n.表达式.标识符.内容;
        if (!文件设置的版本标识符.具有(id)) {
            文件设置的版本标识符.p·设置(id, id);
        }
        if (!在顶级) {
            .编译错误在(n.开始, n.表达式.结束, 诊断集_.版本声明不能位于_语句级版本_块内);
        }
        .完成节点!(版本表达式语句_)(n, 节点开始);
        .编译分号();
        return n;
    }
    else {
        return .在上下文约束内编译!(版本语句_)(节点标志_.在版本验证上下文_, cast(版本语句_ delegate())(编译));
    }
}
测试单元语句_ 编译测试单元语句() {
    测试单元语句_ delegate() 编译;
    bool 嵌套测试;
    测试单元语句_ 编译·func() {
        long 节点开始;
        测试单元语句_ n;
        bool 储存;
        节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
        n = 创建节点!(测试单元语句_)(KSK.测试单元语句);
        n.修饰符 = .全局修饰符数组;
        .编译确定的(KSK.测试_);
        if (嵌套测试) {
            .编译错误在(节点开始, .获取节点开始(), 诊断集_.禁止嵌套测试);
        }
        .编译确定的(KSK.左大括号);
        储存 = .已有启动声明;
        .已有启动声明 = false;
        n.语句组 = .编译列表!(Klang节点_)(编译上下文_.测试单元语句_, cast(Klang节点_ delegate())(·fd(&.编译源码顶级语句)));
        if (!.已有启动声明) {
            .编译错误在(n.开始, n.开始 + 2, 诊断集_.测试单元没有_启动_函数);
        }
        .已有启动声明 = 储存;
        .编译确定的(KSK.右大括号);
        n.版本容器块种类 = 版本容器块种类_.是测试单元_;
        return .完成节点!(测试单元语句_)(n, 节点开始);
    }
    编译 = &编译·func;
    嵌套测试 = false;
    if (.是在上下文内(节点标志_.在测试单元上下文_)) {
        嵌套测试 = true;
    }
    return .在上下文约束内编译!(测试单元语句_)(节点标志_.在测试单元上下文_, cast(测试单元语句_ delegate())(编译));
}
函数声明_ 编译初始函数() {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    函数声明_ n = 创建节点!(函数声明_)(KSK.函数声明);
    n.修饰符 = .全局修饰符数组;
    设置节点标志(n, 节点标志_.是初始函数);
    n.名称 = .编译标识符();
    .完成签名(KSK.冒号, 签名标志_.无_, n);
    n.函数体 = .编译函数块或分号();
    return .完成节点!(函数声明_)(n, 节点开始);
}
函数声明_ 编译启动函数() {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    函数声明_ n = 创建节点!(函数声明_)(KSK.函数声明);
    n.修饰符 = .全局修饰符数组;
    if (.是在上下文内(节点标志_.在测试单元上下文_)) {
        设置节点标志(n, 节点标志_.是测试启动函数);
    }
    else {
        设置节点标志(n, 节点标志_.是启动函数);
    }
    n.名称 = .编译标识符();
    if (.已有启动声明) {
        .编译错误在(n.名称.开始, n.名称.结束, 诊断集_.重复的_启动_声明);
    }
    .已有启动声明 = true;
    .完成签名(KSK.冒号, 签名标志_.无_, n);
    n.函数体 = .编译函数块或分号();
    return .完成节点!(函数声明_)(n, 节点开始);
}
函数声明_ 编译函数声明() {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    函数声明_ n = 创建节点!(函数声明_)(KSK.函数声明);
    n.修饰符 = .全局修饰符数组;
    .编译确定的(KSK.函数_);
    n.名称 = .编译标识符();
    if (n.名称.标识符.内容 == "启动"d) {
        if (.已有启动声明) {
            .编译错误在(n.名称.开始, n.名称.结束, 诊断集_.重复的_启动_声明);
        }
        .已有启动声明 = true;
        if (.是在上下文内(节点标志_.在测试单元上下文_)) {
            设置节点标志(n, 节点标志_.是测试启动函数);
        }
        else {
            设置节点标志(n, 节点标志_.是启动函数);
        }
    }
    else if (n.名称.标识符.内容 == "初始"d) {
        设置节点标志(n, 节点标志_.是初始函数);
    }
    .完成签名(KSK.冒号, 签名标志_.无_, n);
    n.函数体 = .编译函数块或分号();
    return .完成节点!(函数声明_)(n, 节点开始);
}
Klang节点_ 转为声明(Klang节点_ n) {
    return (cast(声明_)(n));
}
对象声明_ 编译对象声明() {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    对象声明_ n = 创建节点!(对象声明_)(KSK.对象声明);
    n.修饰符 = .全局修饰符数组;
    .编译确定的(KSK.对象_);
    n.名称 = .编译标识符();
    n.类型形参 = .编译类型形参组(n);
    if (.是继承子句()) {
        .是在继承子句上下文 = true;
        n.继承子句 = .编译继承子句组();
        .是在继承子句上下文 = false;
    }
    .编译确定的(KSK.左大括号);
    n.成员组 = .编译列表!(Klang节点_)(编译上下文_.对象体成员_, () { return .编译声明成员(编译上下文_.对象体成员_); });
    .编译确定的(KSK.右大括号);
    return .完成节点!(对象声明_)(n, 节点开始);
}
结构声明_ 编译结构声明() {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    结构声明_ n = 创建节点!(结构声明_)(KSK.结构声明);
    n.修饰符 = .全局修饰符数组;
    .编译确定的(KSK.结构_);
    n.名称 = .编译标识符();
    n.类型形参 = .编译类型形参组(n);
    if (.是继承子句()) {
        .是在继承子句上下文 = true;
        n.继承子句 = .编译继承子句组();
        .是在继承子句上下文 = false;
    }
    .编译确定的(KSK.左大括号);
    n.成员组 = .编译列表!(Klang节点_)(编译上下文_.对象体成员_, () { return .编译声明成员(编译上下文_.对象体成员_); });
    .编译确定的(KSK.右大括号);
    return .完成节点!(结构声明_)(n, 节点开始);
}
接口声明_ 编译接口声明() {
    bool 应该取消标志 = false;
    if (!.是在上下文内(节点标志_.Ambient)) {
        .设置标志(节点标志_.Ambient);
        应该取消标志 = true;
    }
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    接口声明_ n = 创建节点!(接口声明_)(KSK.接口声明);
    n.修饰符 = .全局修饰符数组;
    .编译确定的(KSK.接口_);
    n.名称 = .编译标识符();
    n.类型形参 = .编译类型形参组(n);
    if (.是继承子句()) {
        .是在继承子句上下文 = true;
        n.继承子句 = .编译继承子句组();
        .是在继承子句上下文 = false;
    }
    .编译确定的(KSK.左大括号);
    n.成员组 = .编译列表!(Klang节点_)(编译上下文_.接口声明成员_, () { return .编译声明成员(编译上下文_.接口声明成员_); });
    .编译确定的(KSK.右大括号);
    .完成节点!(接口声明_)(n, 节点开始);
    if (应该取消标志) {
        .取消标志(节点标志_.Ambient);
    }
    return n;
}
Klang节点_ 编译声明成员(编译上下文_ 上下文) {
    基础节点.节点数组_!(修饰符_) 修饰符 = .编译修饰符组();
    if ((修饰符 !is null) && (修饰符.原型 !is ··null!(修饰符_[])) && .令牌() == KSK.左大括号) {
        块_ n = 创建节点!(块_)(KSK.块);
        n.版本容器块种类 = 版本容器块种类_.是局部声明块_;
        n.修饰符 = 修饰符;
        .编译确定的(KSK.左大括号);
        n.语句组 = .编译列表!(Klang节点_)(上下文, () { return .编译声明成员(上下文); });
        .编译确定的(KSK.右大括号);
        return .转为声明(.完成节点!(块_)(n, 修饰符.开始));
    }
    if (.是运算符签名()) {
        return .转为声明(.编译运算符签名(修饰符));
    }
    else if (.是索引签名()) {
        return .转为声明(.编译索引签名(修饰符));
    }
    ··Klang节点_.Klang标识符_ 名称 = .编译标识符();
    if (.令牌() == KSK.左括号 || .令牌() == KSK.左尖括号) {
        return .转为声明(.编译方法声明(名称, 修饰符));
    }
    return .转为声明(.编译属性声明(名称, 修饰符));
}
索引签名_ 编译索引签名(基础节点.节点数组_!(修饰符_) 修饰符 = ··null!(基础节点.节点数组_!(修饰符_))) {
    long 节点开始 = 修饰符 ? 修饰符.开始 : .获取节点开始();
    索引签名_ n = 创建节点!(索引签名_)(KSK.索引签名);
    n.修饰符 = 修饰符;
    .编译确定的(KSK.左方括号);
    if (.令牌() == KSK.标识符) {
        n.形参 = .编译形参();
    }
    .编译确定的(KSK.右方括号);
    .编译确定的(KSK.冒号);
    n.类型 = .编译类型();
    .完成节点!(索引签名_)(n, 节点开始);
    .编译分号或逗号();
    return n;
}
运算符签名_ 编译运算符签名(基础节点.节点数组_!(修饰符_) 修饰符 = ··null!(基础节点.节点数组_!(修饰符_))) {
    long 节点开始 = 修饰符 ? 修饰符.开始 : .获取节点开始();
    运算符签名_ n = 创建节点!(运算符签名_)(KSK.运算符签名);
    n.修饰符 = 修饰符;
    .编译确定的(KSK.左方括号);
    n.运算符组 = .编译列表!(运算符签名元素_)(编译上下文_.运算符签名列表, cast(运算符签名元素_ delegate())(·fd(&.编译运算符元素)));
    .编译确定的(KSK.右方括号);
    if (.编译可选的(KSK.冒号)) {
        n.类型 = .编译类型();
    }
    .完成节点!(运算符签名_)(n, 节点开始);
    .编译分号或逗号();
    return n;
}
运算符签名元素_ 编译运算符元素() {
    long 节点开始 = .获取节点开始();
    运算符签名元素_ n = 创建节点!(运算符签名元素_)(KSK.运算符签名元素);
    n.运算符 = .令牌();
    .下个令牌();
    if (.编译可选的(KSK.冒号)) {
        n.类型 = .编译类型();
    }
    .完成节点!(运算符签名元素_)(n, 节点开始);
    逗号编译结果_ 逗号 = .编译逗号(() { return !.是运算符(.令牌()); });
    if (逗号 == 逗号编译结果_.逗号后就结束_) {
        n.后面是逗号 = true;
    }
    return n;
}
Klang节点_ 编译方法声明(··Klang节点_.Klang标识符_ 名称, 基础节点.节点数组_!(修饰符_) 修饰符 = ··null!(基础节点.节点数组_!(修饰符_))) {
    long 节点开始 = 修饰符 ? 修饰符.开始 : 名称.开始;
    if (名称.标识符.内容 == "构建"d) {
        .正在编译构建声明 = true;
        构建声明_ n = 创建节点!(构建声明_)(KSK.构建声明);
        n.修饰符 = 修饰符;
        n.名称 = 名称;
        .完成签名(KSK.冒号, 签名标志_.无_, n);
        n.函数体 = .编译函数块或分号();
        .完成节点!(构建声明_)(n, 节点开始);
        .正在编译构建声明 = false;
        .编译分号或逗号();
        return .转为声明(n);
    }
    else if (名称.标识符.内容 == "释放"d) {
        .正在编译构建声明 = true;
        释放声明_ n = 创建节点!(释放声明_)(KSK.释放声明);
        n.修饰符 = 修饰符;
        n.名称 = 名称;
        .完成签名(KSK.冒号, 签名标志_.无_, n);
        n.函数体 = .编译函数块或分号();
        .完成节点!(释放声明_)(n, 节点开始);
        .正在编译构建声明 = false;
        .编译分号或逗号();
        return .转为声明(n);
    }
    方法声明_ n = 创建节点!(方法声明_)(KSK.方法声明);
    n.修饰符 = 修饰符;
    n.名称 = 名称;
    .完成签名(KSK.冒号, 签名标志_.无_, n);
    n.函数体 = .编译函数块或分号();
    .完成节点!(方法声明_)(n, 节点开始);
    .编译分号或逗号();
    return .转为声明(n);
}
属性声明_ 编译属性声明(··Klang节点_.Klang标识符_ 名称, 基础节点.节点数组_!(修饰符_) 修饰符 = ··null!(基础节点.节点数组_!(修饰符_))) {
    long 节点开始 = 修饰符 ? 修饰符.开始 : 名称.开始;
    属性声明_ n = 创建节点!(属性声明_)(KSK.属性声明);
    n.修饰符 = 修饰符;
    n.名称 = 名称;
    if (.令牌() == KSK.问号) {
        .下个令牌();
        n.问号 = KSK.问号;
    }
    .编译确定的(KSK.冒号);
    n.类型 = .编译类型();
    if (.令牌() == KSK.等号) {
        n.初始化 = .编译初始化();
    }
    .完成节点!(属性声明_)(n, 节点开始);
    .编译分号或逗号();
    return n;
}
bool 是索引签名() {
    return .令牌() == KSK.左方括号 && .向前看!(bool)(cast(bool delegate())(·fd(&.是明确的索引签名)));
}
bool 是明确的索引签名() {
    if (.令牌() == KSK.左方括号) {
        .下个令牌();
        if (.令牌() == KSK.右方括号) {
            return true;
        }
        if (.令牌() != KSK.标识符) {
            return false;
        }
        else {
            .下个令牌();
        }
        if (.令牌() == KSK.冒号) {
            return true;
        }
        .下个令牌();
        return .令牌() == KSK.右方括号;
    }
    return false;
}
bool 是运算符签名() {
    return .令牌() == KSK.左方括号 && .向前看!(bool)(() { return .是运算符(.下个令牌()); });
}
基础节点.节点数组_!(继承子句_) 编译继承子句组() {
    return .编译列表!(继承子句_)(编译上下文_.继承子句组, cast(继承子句_ delegate())(·fd(&.编译继承子句)));
}
继承子句_ 编译继承子句() {
    long 节点开始 = .获取节点开始();
    KSK tok = .令牌();
    assert(tok == KSK.冒号, "继承子句 编译错误"c);
    继承子句_ n = 创建节点!(继承子句_)(KSK.继承子句);
    .下个令牌();
    n.类型组 = .编译列表!(表达式包含类型实参_)(编译上下文_.继承子句组元素, cast(表达式包含类型实参_ delegate())(·fd(&.编译继承子句元素)));
    return .完成节点!(继承子句_)(n, 节点开始);
}
表达式包含类型实参_ 编译继承子句元素() {
    long 节点开始 = .获取节点开始();
    表达式包含类型实参_ n = 创建节点!(表达式包含类型实参_)(KSK.表达式包含类型实参);
    Klang节点_ 表达式 = .编译左侧表达式或更高();
    n.表达式 = 表达式.目标种类 == KSK.表达式包含类型实参 ? (cast(表达式包含类型实参_)(表达式)).表达式 : 表达式;
    n.类型实参组 = 表达式.目标种类 == KSK.表达式包含类型实参 ? (cast(表达式包含类型实参_)(表达式)).类型实参组 : 核心.返回零值!(基础节点.节点数组_!(Klang节点_))();
    .完成节点!(表达式包含类型实参_)(n, 节点开始);
    逗号编译结果_ 逗号 = .编译逗号(() { return .令牌() == KSK.左大括号 || .令牌() == KSK.冒号; });
    if (逗号 == 逗号编译结果_.逗号后就结束_) {
        n.后面是逗号 = true;
    }
    return n;
}
基础节点.节点数组_!(Klang节点_) 尝试编译类型实参组() {
    if (.令牌() == KSK.左尖括号) {
        .编译确定的(KSK.左尖括号);
        基础节点.节点数组_!(Klang节点_) 类型实参组 = .编译列表!(Klang节点_)(编译上下文_.类型实参组, cast(Klang节点_ delegate())(·fd(&.编译类型实参)));
        .编译确定的(KSK.右尖括号);
        return 类型实参组;
    }
    return ··null!(基础节点.节点数组_!(Klang节点_));
}
枚举声明_ 编译枚举声明() {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    枚举声明_ n = 创建节点!(枚举声明_)(KSK.枚举声明);
    n.修饰符 = .全局修饰符数组;
    .编译确定的(KSK.枚举_);
    n.名称 = .编译标识符();
    if (.编译可选的(KSK.冒号)) {
        n.类型 = .编译类型();
    }
    .编译确定的(KSK.左大括号);
    n.成员组 = .编译列表!(枚举成员_)(编译上下文_.枚举成员组, cast(枚举成员_ delegate())(·fd(&.编译枚举成员)));
    .编译确定的(KSK.右大括号);
    return .完成节点!(枚举声明_)(n, 节点开始);
}
枚举成员_ 编译枚举成员() {
    long 节点开始 = .获取节点开始();
    枚举成员_ n = 创建节点!(枚举成员_)(KSK.枚举成员);
    n.名称 = .编译标识符();
    n.初始化 = .编译初始化();
    .完成节点!(枚举成员_)(n, 节点开始);
    .编译分号或逗号();
    return n;
}
别名声明_ 编译类型别名() {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    别名声明_ n = 创建节点!(别名声明_)(KSK.别名声明);
    n.修饰符 = .全局修饰符数组;
    .编译确定的(KSK.别名_);
    n.名称 = .编译标识符();
    n.类型形参 = .编译类型形参组(n);
    .编译确定的(KSK.等号);
    n.类型 = .编译类型();
    .完成节点!(别名声明_)(n, 节点开始);
    .编译分号();
    return n;
}
类型声明_ 编译类型声明() {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    类型声明_ n = 创建节点!(类型声明_)(KSK.类型声明);
    n.修饰符 = .全局修饰符数组;
    .编译确定的(KSK.类型_);
    n.名称 = .编译标识符();
    n.类型形参 = .编译类型形参组(n);
    .编译确定的(KSK.冒号);
    n.类型 = .编译类型();
    .编译确定的(KSK.左大括号);
    n.成员组 = .编译列表!(Klang节点_)(编译上下文_.类型声明成员_, () { return .编译声明成员(编译上下文_.类型声明成员_); });
    .编译确定的(KSK.右大括号);
    return .完成节点!(类型声明_)(n, 节点开始);
}
bool 是继承子句() {
    return .令牌() == KSK.冒号;
}
块_ 编译函数块或分号() {
    if (.令牌() != KSK.左大括号 && .可以编译分号()) {
        .编译分号();
        return ··null!(块_);
    }
    return .编译块();
}
变量语句_ 编译变量声明语句(bool 是全局变量 = false) {
    long 节点开始 = .全局修饰符数组 ? .全局的节点开始位置 : .获取节点开始();
    变量语句_ n = 创建节点!(变量语句_)(KSK.变量语句);
    n.修饰符 = .全局修饰符数组;
    if (是全局变量) {
        .设置标志(节点标志_.全局变量_);
    }
    n.声明列表 = .编译变量声明列表(/*在循环语句初始化*/ false);
    .编译分号();
    .完成节点!(变量语句_)(n, 节点开始);
    .取消标志(节点标志_.全局变量_);
    return n;
}
变量声明列表_ 编译变量声明列表(bool 在循环语句初始化) {
    变量声明_ delegate() 内部编译;
    long 节点开始;
    变量声明列表_ n;
    变量声明_ 内部编译·func() {
        if (在循环语句初始化) {
            变量声明_ 结果 = .编译变量声明不允许叹号();
            逗号编译结果_ 逗号 = .编译逗号(cast(bool delegate())(·fd(&.是变量声明符列表终止符)));
            if (逗号 == 逗号编译结果_.逗号后就结束_) {
                结果.后面是逗号 = true;
            }
            return 结果;
        }
        else {
            变量声明_ 结果 = .编译变量声明允许叹号();
            逗号编译结果_ 逗号 = .编译逗号(cast(bool delegate())(·fd(&.是变量声明符列表终止符)));
            if (逗号 == 逗号编译结果_.逗号后就结束_) {
                结果.后面是逗号 = true;
            }
            return 结果;
        }
    }
    内部编译 = &内部编译·func;
    节点开始 = .获取节点开始();
    n = 创建节点!(变量声明列表_)(KSK.变量声明列表);
    if (.是在上下文内(节点标志_.全局变量_)) {
        if (.令牌() == KSK.变量_) {
            .编译确定的(KSK.变量_);
        }
        else if (.令牌() == KSK.常量_) {
            设置节点标志(n, 节点标志_.Const);
            .编译确定的(KSK.常量_);
        }
        else {
            if (!在循环语句初始化) {
                assert(false, "编译变量声明列表 失败"c);
            }
        }
    }
    else {
        switch (.令牌()) {
            case KSK.变量_: {
                设置节点标志(n, 节点标志_.Let);
                .下个令牌();
                break;
            }
            case KSK.常量_: {
                设置节点标志(n, 节点标志_.Const);
                .下个令牌();
                break;
            }
            default: {
                if (!在循环语句初始化) {
                    assert(false, "编译变量声明列表 失败"c);
                }
            }
        }
    }
    if (.令牌() == KSK.属于_ && .向前看!(bool)(cast(bool delegate())(·fd(&.是可以跟随属于关键字的上下文)))) {
        n.声明组 = .创建失踪列表!(变量声明_)();
    }
    else {
        n.声明组 = .编译列表!(变量声明_)(编译上下文_.变量声明组, cast(变量声明_ delegate())(内部编译));
    }
    return .完成节点!(变量声明列表_)(n, 节点开始);
}
bool 是可以跟随属于关键字的上下文() {
    return .下个令牌是标识符() && .下个令牌() == KSK.右括号;
}
bool 下个令牌是标识符() {
    .下个令牌();
    return .令牌() == KSK.标识符;
}
变量声明_ 编译变量声明允许叹号() {
    return .编译变量声明(/*允许叹号*/ true);
}
变量声明_ 编译变量声明不允许叹号() {
    return .编译变量声明(/*允许叹号*/ false);
}
变量声明_ 编译变量声明(bool 允许叹号 = ··null!(bool)) {
    long 节点开始 = .获取节点开始();
    变量声明_ n = 创建节点!(变量声明_)(KSK.变量声明);
    n.名称 = .编译标识符();
    if (允许叹号 && n.名称.目标种类 == KSK.标识符 && .令牌() == KSK.叹号 && !.前面有换行符()) {
        n.叹号令牌 = .编译klang令牌节点!(KSK)(KSK.叹号);
    }
    n.类型 = .编译类型注释();
    n.初始化 = .编译初始化();
    return .完成节点!(变量声明_)(n, 节点开始);
}
//#范围 编译表达式
bool 是部分输出表达式(基础节点.节点_ n) {
    return n.目标种类 == KSK.部分输出表达式;
}
部分输出表达式_ 获取部分输出表达式(基础节点.节点_ n) {
    if (.是部分输出表达式(n)) {
        return (cast(部分输出表达式_)(n));
    }
    return ··null!(部分输出表达式_);
}
bool 是前缀一元表达式(基础节点.节点_ n) {
    return n.目标种类 == KSK.前缀一元表达式;
}
前缀一元表达式_ 获取前缀一元表达式(基础节点.节点_ n) {
    if (.是前缀一元表达式(n)) {
        return (cast(前缀一元表达式_)(n));
    }
    return ··null!(前缀一元表达式_);
}
基础节点.节点_ 跳过部分输出表达式(基础节点.节点_ n) {
    while(.是部分输出表达式(n)) {
        部分输出表达式_ exNode = .获取部分输出表达式(n);
        if (exNode !is ··null!(部分输出表达式_)) {
            n = exNode.表达式;
        }
    }
    return n;
}
bool 是左侧表达式(基础节点.节点_ n) {
    return .是左侧表达式种类(.跳过部分输出表达式(n).目标种类);
}
bool 是左侧表达式种类(long ksk) {
    switch (ksk) {
        case KSK.属性访问表达式:
        case KSK.元素访问表达式:
        case KSK.新建表达式:
        case KSK.调用表达式:
        case KSK.数组字面量表达式:
        case KSK.表达式列表表达式:
        case KSK.动态类字面量表达式:
        case KSK.词典键值表达式:
        case KSK.结构字面量表达式:
        case KSK.接口字面量表达式:
        case KSK.函数表达式:
        case KSK.正则表达式字面量:
        case KSK.无替换模板字面量:
        case KSK.模板表达式:
        case KSK.非空表达式:
        case KSK.截取表达式:
        case KSK.标识符:
        case KSK.数字字面量:
        case KSK.文本字面量:
        case KSK.零值_:
        case KSK.空址_:
        case KSK.假_:
        case KSK.空值_:
        case KSK.本体_:
        case KSK.原型_:
        case KSK.真_:
        case KSK.前缀一元表达式:
        case KSK.符号引用表达式: {
            return true;
        }
        default: {
            return false;
        }
    }
}
bool 是取值表达式(基础节点.节点_ 表达式) {
    前缀一元表达式_ n = .获取前缀一元表达式(表达式);
    if ((n !is ··null!(前缀一元表达式_)) && n.运算符 == KSK.星号) {
        return true;
    }
    return false;
}
Klang节点_ 编译表达式() {
    Klang节点_ 表达式 = .编译赋值表达式或更高();
    while(.编译可选的(KSK.逗号)) {
        表达式 = .制作二元表达式(表达式, KSK.逗号, .编译赋值表达式或更高());
    }
    return 表达式;
}
Klang节点_ 编译简洁变量初始化表达式() {
    long 节点开始 = .获取节点开始();
    Klang节点_ 表达式 = .编译实参或数组字面量元素();
    Klang节点_[] 表达式组 = [表达式];
    while(.编译可选的(KSK.逗号)) {
        Klang节点_ e = .编译实参或数组字面量元素();
        表达式组 = .追加!(Klang节点_)(表达式组, e);
    }
    if (表达式组.length == 1) {
        return 表达式;
    }
    else {
        表达式列表表达式_ n = 创建节点!(表达式列表表达式_)(KSK.表达式列表表达式);
        n.元素组 = .创建节点数组!(Klang节点_)(表达式组, 节点开始);
        return .完成节点!(表达式列表表达式_)(n, 节点开始);
    }
}
二元表达式_ 制作二元表达式(Klang节点_ 左侧, KSK 运算符, Klang节点_ 右侧) {
    二元表达式_ n = 创建节点!(二元表达式_)(KSK.二元表达式);
    n.左侧 = 左侧;
    n.右侧 = 右侧;
    n.运算符 = 运算符;
    return .完成节点!(二元表达式_)(n, 左侧.开始);
}
KSK 编译运算符() {
    KSK 结果 = .令牌();
    .下个令牌();
    return 结果;
}
Klang节点_ 编译赋值表达式或更高() {
    Klang节点_ 箭头函数 = .尝试编译括号箭头函数表达式();
    if (箭头函数 !is ··null!(Klang节点_)) {
        return 箭头函数;
    }
    Klang节点_ 表达式 = .编译二元表达式或更高(/*优先级*/ 0);
    if ((.是左侧表达式(表达式) || .是取值表达式(表达式)) && 是赋值运算符(.预扫描大于号())) {
        return .制作二元表达式(表达式, .编译运算符(), .编译赋值表达式或更高());
    }
    return .编译条件表达式剩余(表达式);
}
Klang节点_ 编译条件表达式剩余(Klang节点_ 左侧) {
    // Note: we are passed in an 表达式 which was produced from 编译二元表达式或更高.
    bool 有问号 = .编译可选的(KSK.问号);
    if (!有问号) {
        return 左侧;
    }
    条件表达式_ n = 创建节点!(条件表达式_)(KSK.条件表达式);
    n.条件 = 左侧;
    n.问号 = KSK.问号;
    n.当真 = .编译赋值表达式或更高();
    .编译确定的(KSK.冒号);
    n.冒号 = KSK.冒号;
    n.当假 = .编译赋值表达式或更高();
    return .完成节点!(条件表达式_)(n, 左侧.开始);
}
Klang节点_ 编译二元表达式或更高(int 优先级) {
    Klang节点_ 左侧 = .编译一元表达式或更高();
    return .编译二元表达式剩余(优先级, 左侧);
}
Klang节点_ 编译二元表达式剩余(int 优先级, Klang节点_ 左侧) {
    while(true) {
        .预扫描大于号();
        int 新优先级 = .获取二元运算符优先级(.令牌());
        bool 停止当前 = 新优先级 > 优先级;
        if (!停止当前) {
            break;
        }
        左侧 = .制作二元表达式(左侧, .编译运算符(), .编译二元表达式或更高(新优先级));
    }
    return 左侧;
}
bool 是更新表达式() {
    switch (.令牌()) {
        case KSK.加号:
        case KSK.减号:
        case KSK.波折号:
        case KSK.叹号:
        case KSK.左尖括号:
        case KSK.无值_: {
            return false;
        }
        default: {
            return true;
        }
    }
}
Klang节点_ 编译一元表达式或更高() {
    if (.是更新表达式()) {
        Klang节点_ 更新表达式 = .编译更新表达式();
        return 更新表达式;
    }
    Klang节点_ 简单一元表达式 = .编译简单一元表达式();
    return 简单一元表达式;
}
Klang节点_ 编译简单一元表达式() {
    switch (.令牌()) {
        case KSK.加号:
        case KSK.减号:
        case KSK.波折号:
        case KSK.叹号: {
            return .编译前缀一元表达式();
        }
        default: {
            return .编译更新表达式();
        }
    }
}
前缀一元表达式_ 编译前缀一元表达式() {
    long 开始 = .获取节点开始();
    前缀一元表达式_ n = 创建节点!(前缀一元表达式_)(KSK.前缀一元表达式);
    n.运算符 = .令牌();
    .下个令牌();
    n.表达式 = .编译简单一元表达式();
    return .完成节点!(前缀一元表达式_)(n, 开始);
}
Klang节点_ 编译更新表达式() {
    if (.令牌() == KSK.加加号 || .令牌() == KSK.减减号 || .令牌() == KSK.且号 || .令牌() == KSK.星号) {
        bool 储存 = .正在编译取址表达式;
        if (.令牌() == KSK.且号) {
            .正在编译取址表达式 = true;
        }
        bool 是取值表达式 = false;
        if (.令牌() == KSK.星号) {
            是取值表达式 = true;
        }
        long 开始 = .获取节点开始();
        前缀一元表达式_ n = 创建节点!(前缀一元表达式_)(KSK.前缀一元表达式);
        n.运算符 = .令牌();
        .下个令牌();
        n.表达式 = 是取值表达式 || .正在编译取址表达式 ? .编译更新表达式() : .编译左侧表达式或更高();
        .完成节点!(前缀一元表达式_)(n, 开始);
        .正在编译取址表达式 = 储存;
        return n;
    }
    Klang节点_ 表达式 = .编译左侧表达式或更高();
    if ((.令牌() == KSK.加加号 || .令牌() == KSK.减减号) && !.前面有换行符()) {
        long 开始 = .获取节点开始();
        后缀一元表达式_ n = 创建节点!(后缀一元表达式_)(KSK.后缀一元表达式, 表达式.开始);
        n.表达式 = 表达式;
        n.运算符 = .令牌();
        .下个令牌();
        return .完成节点!(后缀一元表达式_)(n, 开始);
    }
    return 表达式;
}
Klang节点_ 编译左侧表达式或更高() {
    Klang节点_ 表达式 = .编译成员表达式或更高();
    表达式 = .编译调用表达式剩余(表达式);
    return 表达式;
}
Klang节点_ 编译调用表达式剩余(Klang节点_ 表达式) {
    while(true) {
        表达式 = .编译成员表达式剩余((cast()(表达式)));
        // handle 'foo<<T>()'
        基础节点.节点数组_!(Klang节点_) 类型实参组;
        if (.令牌() == KSK.左尖括号) {
            类型实参组 = .尝试编译!(基础节点.节点数组_!(Klang节点_))(cast(基础节点.节点数组_!(Klang节点_) delegate())(·fd(&.编译类型实参在表达式)));
            if ((类型实参组 !is null) && (类型实参组.原型 !is ··null!(Klang节点_[]))) {
                if (.令牌() == KSK.左括号) {
                    调用表达式_ 调用表达式 = 创建节点!(调用表达式_)(KSK.调用表达式, 表达式.开始);
                    调用表达式.表达式 = 表达式;
                    调用表达式.类型实参组 = 类型实参组;
                    调用表达式.实参组 = .编译实参列表();
                    表达式 = .完成节点!(调用表达式_)(调用表达式, 表达式.开始);
                    continue;
                }
            }
        }
        else if (.令牌() == KSK.左括号) {
            调用表达式_ 调用表达式 = 创建节点!(调用表达式_)(KSK.调用表达式);
            调用表达式.表达式 = 表达式;
            调用表达式.实参组 = .编译实参列表();
            表达式 = .完成节点!(调用表达式_)(调用表达式, 表达式.开始);
            continue;
        }
        if ((类型实参组 !is null) && (类型实参组.原型 !is ··null!(Klang节点_[]))) {
            表达式包含类型实参_ n = 创建节点!(表达式包含类型实参_)(KSK.表达式包含类型实参);
            n.表达式 = 表达式;
            n.类型实参组 = 类型实参组;
            表达式 = .完成节点!(表达式包含类型实参_)(n, 表达式.开始);
        }
        // 类型转换或类型断言表达式 不允许链式调用
        if (.编译可选的(KSK.点左尖括号)) {
            .有静态表达式 = true;
            if (.令牌() == KSK.类型_) {
                // xxx.xxx.<类型>
                类型查询表达式_ exp = 创建节点!(类型查询表达式_)(KSK.类型查询表达式);
                exp.类型 = .编译类型();
                exp.表达式 = 表达式;
                .编译确定的(KSK.右尖括号);
                表达式 = .完成节点!(类型查询表达式_)(exp, 表达式.开始);
            }
            else {
                类型断言表达式_ exp = 创建节点!(类型断言表达式_)(KSK.类型断言表达式);
                exp.表达式 = 表达式;
                exp.类型 = .编译类型();
                exp.断言标志 = AssertFlags.无_;
                .编译确定的(KSK.右尖括号);
                表达式 = .完成节点!(类型断言表达式_)(exp, 表达式.开始);
            }
            break;
        }
        if (!.是在继承子句上下文 && .编译可选的(KSK.左大括号)) {
            结构字面量表达式_ n = 创建节点!(结构字面量表达式_)(KSK.结构字面量表达式);
            n.类型注释节点 = 表达式;
            if (.前面有换行符()) {
                n.多行 = true;
            }
            bool 储存包含展开表达式 = .包含展开表达式;
            n.属性组 = .编译非JSON结构属性();
            .编译确定的(KSK.右大括号);
            表达式 = .完成节点!(结构字面量表达式_)(n, 表达式.开始);
            if (.包含展开表达式) {
                设置节点标志(表达式, 节点标志_.包含展开表达式_);
            }
            .包含展开表达式 = 储存包含展开表达式;
            break;
        }
        if (.令牌() == KSK.冒号 && .允许词典键值表达式) {
            .允许词典键值表达式 = false;
            .包含词典键值表达式 = true;
            词典键值表达式_ n = 创建节点!(词典键值表达式_)(KSK.词典键值表达式);
            n.键表达式 = 表达式;
            .编译确定的(KSK.冒号);
            n.值表达式 = .编译赋值表达式或更高();
            表达式 = .完成节点!(词典键值表达式_)(n, 表达式.开始);
        }
        break;
    }
    return 表达式;
}
基础节点.节点数组_!(Klang节点_) 编译类型实参在表达式() {
    if (.编译可选的(KSK.左尖括号)) {
        基础节点.节点数组_!(Klang节点_) 类型实参组 = .编译列表!(Klang节点_)(编译上下文_.类型实参组, cast(Klang节点_ delegate())(·fd(&.编译类型实参)));
        if (!.编译确定的(KSK.右尖括号)) {
            return ··null!(基础节点.节点数组_!(Klang节点_));
        }
        if ((类型实参组 !is null) && (类型实参组.原型 !is ··null!(Klang节点_[])) && .可以允许类型参数在表达式()) {
            return 类型实参组;
        }
    }
    return ··null!(基础节点.节点数组_!(Klang节点_));
}
Klang节点_ 编译类型实参() {
    Klang节点_ t = .编译类型();
    逗号编译结果_ 逗号 = .编译逗号(() { return .令牌() == KSK.右尖括号; });
    if (逗号 == 逗号编译结果_.逗号后就结束_) {
        t.后面是逗号 = true;
    }
    return t;
}
基础节点.节点数组_!(Klang节点_) 编译实参列表() {
    .编译确定的(KSK.左括号);
    基础节点.节点数组_!(Klang节点_) 结果 = .编译列表!(Klang节点_)(编译上下文_.实参表达式组, cast(Klang节点_ delegate())(·fd(&.编译实参列表成员)));
    .编译确定的(KSK.右括号);
    return 结果;
}
Klang节点_ 编译实参列表成员() {
    if (.令牌() == KSK.逗号) {
        long 开始 = .获取节点开始();
        省略表达式_ n = 创建节点!(省略表达式_)(KSK.省略表达式);
        .完成节点!(省略表达式_)(n, 开始);
        逗号编译结果_ 逗号 = .编译逗号(() { return .令牌() == KSK.右括号; });
        if (逗号 == 逗号编译结果_.逗号后就结束_) {
            n.后面是逗号 = true;
        }
        return n;
    }
    Klang节点_ 结果 = .编译实参或数组字面量元素();
    逗号编译结果_ 逗号 = .编译逗号(() { return .令牌() == KSK.右括号; });
    if (逗号 == 逗号编译结果_.逗号后就结束_) {
        结果.后面是逗号 = true;
    }
    return 结果;
}
Klang节点_ 编译实参或数组字面量元素() {
    return .令牌() == KSK.三点号 ? .编译展开元素() : .编译赋值表达式或更高();
}
Klang节点_ 编译展开元素() {
    .包含展开表达式 = true;
    long 开始 = .获取节点开始();
    展开表达式_ n = 创建节点!(展开表达式_)(KSK.展开表达式);
    .编译确定的(KSK.三点号);
    n.表达式 = .编译赋值表达式或更高();
    return .完成节点!(展开表达式_)(n, 开始);
}
bool 可以允许类型参数在表达式() {
    switch (.令牌()) {
        case KSK.点左括号:
        case KSK.点左尖括号:
        case KSK.点左方括号:
        case KSK.左方括号:
        case KSK.左括号: // foo<x>(
        case KSK.点号: // foo<x>.
        case KSK.右括号: // foo<x>)
        case KSK.右方括号: // foo<x>]
        case KSK.冒号: // foo<x>:
        case KSK.分号: // foo<x>;
        case KSK.问号: // foo<x>?
        case KSK.等等号: // foo<x> ==
        case KSK.叹等号: // foo<x> !=
        case KSK.且且号: // foo<x> &&
        case KSK.或或号: // foo<x> ||
        case KSK.异或号: // foo<x> ^
        case KSK.且号: // foo<x> &
        case KSK.或号: // foo<x> |
        case KSK.左大括号: // foo<x> }
        case KSK.文件结尾: // foo<x>
        case KSK.标识符:
        case KSK.逗号: {
            return true;
        }
        case KSK.右大括号: {
            return !.是在继承子句上下文;
        }
        default: {
            return false;
        }
    }
}
Klang节点_ 编译成员表达式或更高() {
    Klang节点_ 表达式 = .编译主表达式();
    return .编译成员表达式剩余((cast()(表达式)));
}
Klang节点_ 编译成员表达式剩余(Klang节点_ 表达式) {
    while(true) {
        bool 是属性访问 = .编译可选的(KSK.点号);
        if (是属性访问) {
            表达式 = .编译属性访问表达式剩余(表达式);
            continue;
        }
        if (.令牌() == KSK.叹号 && !.有间隔()) {
            .下个令牌();
            非空表达式_ 非空表达式 = 创建节点!(非空表达式_)(KSK.非空表达式);
            非空表达式.表达式 = 表达式;
            表达式 = .完成节点!(非空表达式_)(非空表达式, 表达式.开始);
            continue;
        }
        if (.编译可选的(KSK.点左括号)) {
            类型转换表达式_ n = 创建节点!(类型转换表达式_)(KSK.类型转换表达式);
            n.表达式 = 表达式;
            n.类型 = .编译类型();
            .编译确定的(KSK.右括号);
            表达式 = .完成节点!(类型转换表达式_)(n, 表达式.开始);
            continue;
        }
        if (.编译可选的(KSK.左方括号)) {
            表达式 = .编译元素访问表达式剩余(表达式);
            continue;
        }
        return 表达式;
    }
}
基础节点.节点数组_!(Klang节点_) 解析标识符类型实参() {
    .编译确定的(KSK.左尖括号);
    基础节点.节点数组_!(Klang节点_) 类型实参组 = .编译列表!(Klang节点_)(编译上下文_.类型实参组, cast(Klang节点_ delegate())(·fd(&.编译类型实参)));
    if (!.编译确定的(KSK.右尖括号)) {
        return ··null!(基础节点.节点数组_!(Klang节点_));
    }
    return 类型实参组;
}
截取表达式_ 编译截取表达式(Klang节点_ 表达式) {
    截取表达式_ 截取表达式 = 创建节点!(截取表达式_)(KSK.截取表达式);
    截取表达式.表达式 = 表达式;
    if (.编译可选的(KSK.二点号)) {
        if (.编译可选的(KSK.右方括号)) {
            return .完成节点!(截取表达式_)(截取表达式, 表达式.开始);
        }
        .允许美元标识符 = true;
        截取表达式.截取结尾 = .编译表达式();
        .允许美元标识符 = false;
        .编译确定的(KSK.右方括号);
        return .完成节点!(截取表达式_)(截取表达式, 表达式.开始);
    }
    else {
        截取表达式.截取开始 = .编译表达式();
        .编译可选的(KSK.二点号);
        if (.编译可选的(KSK.右方括号)) {
            return .完成节点!(截取表达式_)(截取表达式, 表达式.开始);
        }
        .允许美元标识符 = true;
        截取表达式.截取结尾 = .编译表达式();
        .允许美元标识符 = false;
        .编译确定的(KSK.右方括号);
        return .完成节点!(截取表达式_)(截取表达式, 表达式.开始);
    }
}
元素访问表达式_ 编译元素访问表达式剩余(Klang节点_ 表达式) {
    元素访问表达式_ 索引访问 = 创建节点!(元素访问表达式_)(KSK.元素访问表达式);
    索引访问.表达式 = 表达式;
    if (.令牌() != KSK.右方括号) {
        索引访问.参数表达式 = .编译表达式();
    }
    .编译确定的(KSK.右方括号);
    return .完成节点!(元素访问表达式_)(索引访问, 表达式.开始);
}
bool 是截取表达式语法() {
    if (.编译可选的(KSK.二点号)) {
        return true;
    }
    Klang节点_ ex = .编译表达式();
    if (编译器.计算编译错误(ex)) {
        return false;
    }
    return .编译可选的(KSK.二点号);
}
属性访问表达式_ 编译属性访问表达式剩余(Klang节点_ 表达式) {
    属性访问表达式_ 属性访问 = 创建节点!(属性访问表达式_)(KSK.属性访问表达式);
    属性访问.左侧 = 表达式;
    属性访问.名称 = .编译点的右侧();
    return .完成节点!(属性访问表达式_)(属性访问, 表达式.开始);
}
Klang节点_ 编译主表达式() {
    switch (.令牌()) {
        case KSK.点左括号: {
            long 开始 = .获取节点开始();
            类型转换表达式_ 表达式 = 创建节点!(类型转换表达式_)(KSK.类型转换表达式);
            .编译确定的(KSK.点左括号);
            表达式.表达式 = .编译表达式();
            .编译确定的(KSK.右括号);
            return .完成节点!(类型转换表达式_)(表达式, 开始);
        }
        case KSK.数字字面量: {
            return .编译数字字面量表达式();
        }
        case KSK.文本字面量: {
            return .编译文本字面量表达式();
        }
        case KSK.除号:
        case KSK.除等号: {
            return .编译正则表达式表达式();
        }
        case KSK.原型_:
        case KSK.基类_:
        case KSK.本体_:
        case KSK.零值_:
        case KSK.空址_:
        case KSK.空值_:
        case KSK.真_:
        case KSK.假_:
        case KSK.不及_: {
            return .编译确定klang令牌!(KSK)(.令牌());
        }
        case KSK.左括号: {
            return .编译括号表达式();
        }
        case KSK.左方括号: {
            return .编译数组字面量表达式();
        }
        case KSK.左大括号: {
            return .编译词典或动态类字面量表达式();
        }
        case KSK.函数_: {
            return .编译函数表达式();
        }
        case KSK.对象_: {
            return .编译对象表达式();
        }
        case KSK.新建_: {
            return .编译新建表达式或点目标();
        }
        case KSK.共享_:
        case KSK.只读_:
        case KSK.恒定_: {
            if (.向前看!(bool)(cast(bool delegate())(·fd(&.是限定符类型转换表达式)))) {
                long 类型转换开始 = .获取节点开始();
                类型转换表达式_ 表达式 = 创建节点!(类型转换表达式_)(KSK.类型转换表达式);
                表达式.类型 = .编译klang令牌节点!(KSK)(.令牌());
                .编译确定的(KSK.点左括号);
                表达式.表达式 = .编译表达式();
                .编译确定的(KSK.右括号);
                .下个令牌();
                return .完成节点!(类型转换表达式_)(表达式, 类型转换开始);
            }
            long 符号引用开始 = .获取节点开始();
            符号引用表达式_ ex = 创建节点!(符号引用表达式_)(KSK.符号引用表达式);
            ex.修饰符 = .编译修饰符组();
            ex.表达式 = .编译标识符(诊断集_.Expression_expected);
            return .完成节点!(符号引用表达式_)(ex, 符号引用开始);
        }
        default: break;
    }
    long 表达式开始 = .获取节点开始();
    符号引用表达式_ ex = 创建节点!(符号引用表达式_)(KSK.符号引用表达式);
    ex.表达式 = .编译标识符(诊断集_.Expression_expected);
    return .完成节点!(符号引用表达式_)(ex, 表达式开始);
}
bool 是限定符类型转换表达式() {
    .下个令牌();
    return .令牌() == KSK.点左括号;
}
bool 可以允许有修饰符() {
    return .令牌是标识符或关键字(.令牌());
}
bool 下个令牌是在同一行且可以有修饰符() {
    .下个令牌();
    if (.前面有换行符()) {
        return false;
    }
    return .可以允许有修饰符();
}
bool 下个令牌可以有修饰符() {
    switch (.令牌()) {
        case KSK.私有_:
        case KSK.保护_:
        case KSK.静态_:
        case KSK.只读_:
        case KSK.恒定_:
        case KSK.共享_:
        case KSK.引用_:
        case KSK.局部_:
        case KSK.固定_:
        case KSK.重载_:
        case KSK.声明_:
        case KSK.返回_:
        case KSK.返回局部引用_:
        case KSK.返回引用_:
        case KSK.局部引用_:
        case KSK.返回局部_: {
            .下个令牌();
            if (.令牌() == KSK.左大括号) {
                return true;
            }
            return .可以允许有修饰符();
        }
        case KSK.外部_: {
            return .向前看!(bool)(cast(bool delegate())(·fd(&.是外部修饰符)));
        }
        case KSK.左大括号: {
            return true;
        }
        default: {
            return .下个令牌是在同一行且可以有修饰符();
        }
    }
}
bool 可以编译任意修饰符() {
    return .是修饰符种类(.令牌()) && .尝试编译!(bool)(cast(bool delegate())(·fd(&.下个令牌可以有修饰符)));
}
基础节点.节点数组_!(修饰符_) 编译修饰符组() {
    修饰符_[] 修饰符组;
    long 列表开始 = .获取节点开始();
    while(true) {
        long 修饰符开始 = .获取节点开始();
        KSK 修饰符种类 = .令牌();
        if (修饰符种类 != KSK.外部_) {
            if (!.可以编译任意修饰符()) {
                break;
            }
            修饰符_ 修饰符 = 创建节点!(修饰符_)(修饰符种类);
            if (修饰符组 is ··null!(修饰符_[])) {
                修饰符组 = [];
            }
            long 索引 = 查找数组索引!(修饰符_)(修饰符组, (修饰符_ e) { return e.目标种类 == 修饰符.目标种类; });
            if (索引 != -1) {
                .编译错误在(修饰符.开始, .获取节点开始(), 诊断集_.重复修饰符);
            }
            .完成节点!(修饰符_)(修饰符, 修饰符开始);
            修饰符组 = .追加!(修饰符_)(修饰符组, 修饰符);
        }
        else {
            if (修饰符组 is ··null!(修饰符_[])) {
                修饰符组 = [];
            }
            修饰符组 = .追加!(修饰符_)(修饰符组, .编译外部修饰符声明());
        }
    }
    if (修饰符组 !is ··null!(修饰符_[])) {
        return .创建节点数组!(修饰符_)(修饰符组, 列表开始);
    }
    return ··null!(基础节点.节点数组_!(修饰符_));
}
外部修饰符声明_ 编译外部修饰符声明() {
    long 节点开始 = .获取节点开始();
    外部修饰符声明_ n = 创建节点!(外部修饰符声明_)(KSK.外部修饰符声明);
    .编译确定的(KSK.外部_);
    .编译确定的(KSK.左括号);
    修饰符_ 修饰符 = 创建节点!(修饰符_)(.令牌());
    .下个令牌();
    n.修饰符节点 = 修饰符;
    if (修饰符.目标种类 == KSK.C加加_ && .编译可选的(KSK.逗号)) {
        n.名称空间 = .编译实体名称();
    }
    .编译确定的(KSK.右括号);
    return .完成节点!(外部修饰符声明_)(n, 节点开始);
}
新建表达式_ 编译新建表达式或点目标() {
    long 节点开始 = .获取节点开始();
    新建表达式_ n = 创建节点!(新建表达式_)(KSK.新建表达式);
    .编译确定的(KSK.新建_);
    n.类型 = .编译类型();
    bool 有初始 = .编译可选的(KSK.左括号);
    if (有初始) {
        n.实参组 = .编译列表!(Klang节点_)(编译上下文_.实参表达式组, cast(Klang节点_ delegate())(·fd(&.编译实参列表成员)));
        .编译确定的(KSK.右括号);
    }
    return .完成节点!(新建表达式_)(n, 节点开始);
}
函数表达式_ 编译函数表达式() {
    long 节点开始 = .获取节点开始();
    函数表达式_ n = 创建节点!(函数表达式_)(KSK.函数表达式);
    .编译确定的(KSK.函数_);
    n.名称 = .编译标识符();
    .完成签名(KSK.冒号, 签名标志_.无_, n);
    n.函数体 = .编译函数块();
    return .完成节点!(函数表达式_)(n, 节点开始);
}
接口字面量表达式_ 编译对象表达式() {
    long 节点开始 = .获取节点开始();
    接口字面量表达式_ n = 创建节点!(接口字面量表达式_)(KSK.接口字面量表达式);
    .编译确定的(KSK.对象_);
    if (.编译可选的(KSK.冒号)) {
        n.类型 = .编译类型引用();
    }
    .编译确定的(KSK.左大括号);
    if (.前面有换行符()) {
        n.多行 = true;
    }
    n.属性组 = .编译接口字面量成员组();
    .编译确定的(KSK.右大括号);
    return .完成节点!(接口字面量表达式_)(n, 节点开始);
}
基础节点.节点数组_!(Klang节点_) 编译非JSON结构属性() {
    return .编译列表!(Klang节点_)(编译上下文_.结构对象字面量成员组, cast(Klang节点_ delegate())(·fd(&.编译结构字面量元素)));
}
Klang节点_ 编译结构字面量元素() {
    if (.令牌() == KSK.三点号) {
        Klang节点_ 结果 = .编译展开元素();
        .编译分号或逗号();
        return 结果;
    }
    bool 令牌是标识符 = .是标识符();
    long 开始 = .获取节点开始();
    ··Klang节点_.Klang标识符_ 名称 = .编译标识符();
    bool 是简洁属性赋值 = 令牌是标识符 && (.令牌() != KSK.冒号);
    if (是简洁属性赋值) {
        简洁属性赋值_ n = 创建节点!(简洁属性赋值_)(KSK.简洁属性赋值);
        n.名称 = 名称;
        if (.编译可选的(KSK.等号)) {
            n.等号 = KSK.等号;
            n.初始化 = .编译赋值表达式或更高();
        }
        简洁属性赋值_ 结果 = .完成节点!(简洁属性赋值_)(n, 开始);
        .编译分号或逗号();
        return 结果;
    }
    else {
        属性赋值_ n = 创建节点!(属性赋值_)(KSK.属性赋值);
        n.名称 = 名称;
        .编译确定的(KSK.冒号);
        (cast(属性赋值_)(n)).初始化 = .编译赋值表达式或更高();
        属性赋值_ 结果 = .完成节点!(属性赋值_)(n, 开始);
        .编译分号或逗号();
        return 结果;
    }
}
基础节点.节点数组_!(Klang节点_) 编译接口字面量成员组() {
    return .编译列表!(Klang节点_)(编译上下文_.接口字面量成员组, cast(Klang节点_ delegate())(·fd(&.编译对象字面量元素)));
}
Klang节点_ 编译对象字面量元素() {
    bool 令牌是标识符 = .是标识符();
    long 开始 = .获取节点开始();
    ··Klang节点_.Klang标识符_ 名称 = .编译标识符();
    bool 是简洁属性赋值 = 令牌是标识符 && (.令牌() != KSK.冒号);
    if (是简洁属性赋值) {
        简洁属性赋值_ n = 创建节点!(简洁属性赋值_)(KSK.简洁属性赋值);
        n.名称 = 名称;
        if (.编译可选的(KSK.等号)) {
            n.等号 = KSK.等号;
            n.初始化 = .编译赋值表达式或更高();
        }
        简洁属性赋值_ 结果 = .完成节点!(简洁属性赋值_)(n, 开始);
        .编译分号或逗号();
        return 结果;
    }
    else {
        属性赋值_ n = 创建节点!(属性赋值_)(KSK.属性赋值);
        n.名称 = 名称;
        .编译确定的(KSK.冒号);
        (cast(属性赋值_)(n)).初始化 = .编译赋值表达式或更高();
        属性赋值_ 结果 = .完成节点!(属性赋值_)(n, 开始);
        .编译分号或逗号();
        return 结果;
    }
}
块_ 编译函数块() {
    return .编译块();
}
块_ 编译块() {
    long 节点开始 = .获取节点开始();
    块_ n = 创建节点!(块_)(KSK.块);
    .编译确定的(KSK.左大括号);
    if (.前面有换行符()) {
        n.多行 = true;
    }
    n.语句组 = .编译列表!(Klang节点_)(编译上下文_.块语句组, cast(Klang节点_ delegate())(·fd(&.编译语句)));
    .编译确定的(KSK.右大括号);
    .完成节点!(块_)(n, 节点开始);
    return n;
}
Klang节点_ 编译括号表达式() {
    .编译确定的(KSK.左括号);
    Klang节点_ 表达式 = .编译表达式();
    设置节点标志(表达式, 节点标志_.括号表达式);
    .编译确定的(KSK.右括号);
    return 表达式;
}
数组字面量表达式_ 编译数组字面量表达式() {
    long 开始 = .获取节点开始();
    数组字面量表达式_ n = 创建节点!(数组字面量表达式_)(KSK.数组字面量表达式);
    .编译确定的(KSK.左方括号);
    if (.前面有换行符()) {
        n.多行 = true;
    }
    bool 储存包含展开表达式 = .包含展开表达式;
    n.元素组 = .编译列表!(Klang节点_)(编译上下文_.数组字面量成员组, cast(Klang节点_ delegate())(·fd(&.编译数组成员元素)));
    if (.包含展开表达式) {
        设置节点标志(n, 节点标志_.包含展开表达式_);
    }
    .包含展开表达式 = 储存包含展开表达式;
    .编译确定的(KSK.右方括号);
    return .完成节点!(数组字面量表达式_)(n, 开始);
}
Klang节点_ 编译数组成员元素() {
    Klang节点_ 结果 = .编译实参或数组字面量元素();
    逗号编译结果_ 逗号 = .编译逗号(() { return .令牌() == KSK.右方括号; });
    if (逗号 == 逗号编译结果_.逗号后就结束_) {
        结果.后面是逗号 = true;
    }
    return 结果;
}
Klang节点_ 编译动态数组成员元素() {
    .允许词典键值表达式 = true;
    Klang节点_ 结果 = .编译实参或数组字面量元素();
    .允许词典键值表达式 = false;
    逗号编译结果_ 逗号 = .编译逗号(() { return .令牌() == KSK.右大括号; });
    if (逗号 == 逗号编译结果_.逗号后就结束_) {
        结果.后面是逗号 = true;
    }
    return 结果;
}
Klang节点_ 编译词典或动态类字面量表达式() {
    long 开始 = .获取节点开始();
    .编译确定的(KSK.左大括号);
    动态类字面量表达式_ n = 创建节点!(动态类字面量表达式_)(KSK.动态类字面量表达式);
    bool 存储包含词典键值表达式 = .包含词典键值表达式;
    bool 储存包含展开表达式 = .包含展开表达式;
    n.元素组 = .编译列表!(Klang节点_)(编译上下文_.数组字面量成员组, cast(Klang节点_ delegate())(·fd(&.编译动态数组成员元素)));
    if (.包含词典键值表达式) {
        设置节点标志(n, 节点标志_.包含词典键值表达式_);
    }
    if (.包含展开表达式) {
        设置节点标志(n, 节点标志_.包含展开表达式_);
    }
    .包含词典键值表达式 = 存储包含词典键值表达式;
    .包含展开表达式 = 储存包含展开表达式;
    if (.前面有换行符()) {
        n.多行 = true;
    }
    .编译确定的(KSK.右大括号);
    return .完成节点!(动态类字面量表达式_)(n, 开始);
}
Klang节点_ 编译词典字面量元素() {
    if (.令牌() == KSK.三点号) {
        return .编译展开元素();
    }
    long 开始 = .获取节点开始();
    词典键值表达式_ n = 创建节点!(词典键值表达式_)(KSK.词典键值表达式);
    n.键表达式 = .编译赋值表达式或更高();
    .编译确定的(KSK.冒号);
    n.值表达式 = .编译赋值表达式或更高();
    词典键值表达式_ 结果 = .完成节点!(词典键值表达式_)(n, 开始);
    逗号编译结果_ 逗号 = .编译逗号(() { return .令牌() == KSK.右大括号; });
    if (逗号 == 逗号编译结果_.逗号后就结束_) {
        结果.后面是逗号 = true;
    }
    return 结果;
}
三元值_ 是括号箭头函数表达式() {
    if (.令牌() == KSK.左括号) {
        return .向前看!(三元值_)(cast(三元值_ delegate())(·fd(&.是括号箭头函数表达式平台)));
    }
    if (.令牌() == KSK.等右尖号) {
        // 编译错误
        return 三元值_.真_;
    }
    return 三元值_.假_;
}
Klang节点_ 尝试编译括号箭头函数表达式() {
    long 节点开始 = .获取节点开始();
    三元值_ 三元值 = .是括号箭头函数表达式();
    if (三元值 == 三元值_.假_) {
        // It's definitely not a parenthesized arrow 函数 表达式.
        return ··null!(Klang节点_);
    }
    箭头函数_ 箭头函数 = 三元值 == 三元值_.真_ ? .编译括号箭头函数表达式头() : .尝试编译!(箭头函数_)(cast(箭头函数_ delegate())(·fd(&.编译可能的括号箭头函数表达式头)));
    if (箭头函数 is ··null!(箭头函数_)) {
        // Didn't appear to actually be a parenthesized arrow 函数.  Just bail out.
        return ··null!(Klang节点_);
    }
    KSK 最后令牌 = .令牌();
    箭头函数.等右尖号 = .编译确定klang令牌!(KSK)(KSK.等右尖号);
    箭头函数.函数体 = (最后令牌 == KSK.等右尖号 || 最后令牌 == KSK.左大括号) ? .编译箭头函数表达式函数体() : .编译标识符();
    return .完成节点!(箭头函数_)(箭头函数, 节点开始);
}
bool 是表达式语句的开始() {
    // As per the grammar, none of '{' or 'function' or 'class' can 节点开始 an expression statement.
    return .令牌() != KSK.左大括号 && .令牌() != KSK.函数_ && .令牌() != KSK.艾特 && .是表达式开始();
}
Klang节点_ 编译箭头函数表达式函数体() {
    if (.令牌() == KSK.左大括号) {
        return .编译函数块();
    }
    if (.令牌() != KSK.分号 && .令牌() != KSK.函数_ && .是语句的开始() && !.是表达式语句的开始()) {
        return .编译函数块();
    }
    return .编译赋值表达式或更高();
}
三元值_ 是括号箭头函数表达式平台() {
    KSK 第一个 = .令牌();
    KSK 第二个 = .下个令牌();
    if (第一个 == KSK.左括号) {
        if (第二个 == KSK.右括号) {
            KSK 第三个 = .下个令牌();
            switch (第三个) {
                case KSK.等右尖号:
                case KSK.冒号:
                case KSK.左大括号: {
                    return 三元值_.真_;
                }
                default: {
                    return 三元值_.假_;
                }
            }
        }
        while(第二个 == KSK.返回_ || 第二个 == KSK.局部_ || 第二个 == KSK.引用_ || 第二个 == KSK.返回局部_ || 第二个 == KSK.返回引用_ || 第二个 == KSK.局部引用_ || 第二个 == KSK.返回局部引用_) {
            第二个 = .下个令牌();
        }
        if (!.是标识符()) {
            return 三元值_.假_;
        }
        switch (.下个令牌()) {
            case KSK.冒号: {
                return 三元值_.真_;
            }
            case KSK.逗号:
            case KSK.等号:
            case KSK.右括号: {
                return 三元值_.未知_;
            }
            default: break;
        }
    }
    return 三元值_.假_;
}
箭头函数_ 编译括号箭头函数表达式头() {
    箭头函数_ n = 创建节点!(箭头函数_)(KSK.箭头函数);
    if (.完成签名(KSK.冒号, 签名标志_.无_, n)) {
        return n;
    }
    return ··null!(箭头函数_);
}
箭头函数_ 编译可能的括号箭头函数表达式头() {
    long 节点开始 = .获取令牌开始();
    if (非括号箭头.具有(·to!(dstring)(节点开始))) {
        return ··null!(箭头函数_);
    }
    箭头函数_ 结果 = .编译括号箭头函数表达式头();
    if (结果 is ··null!(箭头函数_)) {
        非括号箭头.p·设置(·to!(dstring)(节点开始), true);
        return ··null!(箭头函数_);
    }
    return 结果;
}
bool 应编译返回类型(KSK 返回令牌, bool isType) {
    if (返回令牌 == KSK.等右尖号) {
        .编译确定的(返回令牌);
        return true;
    }
    else if (.编译可选的(KSK.冒号)) {
        return true;
    }
    else if (isType && .令牌() == KSK.等右尖号) {
        .报告当前令牌编译错误(诊断集_.a0_expected, 获取KSK关键字文本(KSK.冒号));
        .下个令牌();
        return true;
    }
    return false;
}
/**
 * Note: If 返回令牌 is 等右尖号, `signature.type` will always be defined.
 * @returns If 返回 type parsing succeeds
 **/
bool 完成签名(KSK 返回令牌, 签名标志_ 标志, 签名声明_ 签名节点) {
    签名节点.类型形参 = .编译类型形参组(签名节点);
    bool 编译成功 = .编译形参列表(签名节点, 标志);
    if (.应编译返回类型(返回令牌, (标志 & 签名标志_.类型) != 0)) {
        Klang节点_ tn = .编译类型();
        Klang节点_[] tns = [tn];
        while(.令牌() == KSK.逗号 && .向前看!(bool)(cast(bool delegate())(·fd(&.下个元素是多返回值列表)))) {
            .下个令牌();
            tns = .追加!(Klang节点_)(tns, .编译类型());
        }
        if (tns.length > 1) {
            类型列表_ 多返回类型注释节点 = 创建节点!(类型列表_)(KSK.类型列表);
            多返回类型注释节点.类型组 = .创建节点数组!(Klang节点_)(tns, tn.开始);
            tn = .完成节点!(类型列表_)(多返回类型注释节点, tn.开始);
        }
        签名节点.类型 = tn;
        if (.类型具有阻止编译错误的箭头函数(签名节点.类型)) {
            return false;
        }
    }
    return 编译成功;
}
bool 下个元素是多返回值列表() {
    if (.令牌() == KSK.逗号) {
        .下个令牌();
        return !.是形参的开始(true) && .是类型的开始();
    }
    return false;
}
//#结束范围
//#范围 编译类型
Klang节点_ 编译类型() {
    return .编译类型平台();
}
Klang节点_ 编译类型平台() {
    if (.是函数类型的开始()) {
        return .编译函数或构建类型();
    }
    return .编译联合类型或更高();
}
变长参数_ 编译变长参数类型节点() {
    long 开始 = .获取节点开始();
    变长参数_ tn = 创建节点!(变长参数_)(KSK.变长参数);
    .编译确定的(KSK.三点号);
    tn.类型 = .编译类型运算或更高();
    return .完成节点!(变长参数_)(tn, 开始);
}
Klang节点_ 编译类型运算或更高() {
    if (.令牌() == KSK.三点号) {
        return .编译变长参数类型节点();
    }
    return .编译前缀类型或更高();
}
Klang节点_ 编译前缀类型或更高() {
    Klang节点_ type = .编译非数组类型();
    while(!.前面有换行符()) {
        switch (.令牌()) {
            case KSK.左方括号: {
                .编译确定的(KSK.左方括号);
                if (.编译可选的(KSK.右方括号)) {
                    // 文本[]
                    动态数组类型_ n = 创建节点!(动态数组类型_)(KSK.动态数组类型);
                    n.类型 = type;
                    type = .完成节点!(动态数组类型_)(n, type.开始);
                    break;
                }
                if (.编译可选的(KSK.二点号)) {
                    // 文本[..]
                    数组类型_ n = 创建节点!(数组类型_)(KSK.数组类型);
                    n.类型 = type;
                    .编译确定的(KSK.右方括号);
                    type = .完成节点!(数组类型_)(n, type.开始);
                    break;
                }
                // 文本[3]
                .允许类型计算 = true;
                数组类型_ n = 创建节点!(数组类型_)(KSK.数组类型);
                n.类型 = type;
                n.长度 = .编译类型();
                .允许类型计算 = false;
                .编译确定的(KSK.右方括号);
                type = .完成节点!(数组类型_)(n, type.开始);
                break;
            }
            case KSK.点左方括号: {
                // 文本.[整数]
                .编译确定的(KSK.点左方括号);
                词典类型_ n = 创建节点!(词典类型_)(KSK.词典类型);
                n.值类型 = type;
                n.键类型 = .编译类型();
                .编译确定的(KSK.右方括号);
                type = .完成节点!(词典类型_)(n, type.开始);
                break;
            }
            case KSK.星号: {
                .编译确定的(KSK.星号);
                指针类型_ n = 创建节点!(指针类型_)(KSK.指针类型);
                n.类型 = type;
                type = .完成节点!(指针类型_)(n, type.开始);
                break;
            }
            case KSK.加号:
            case KSK.减号:
            case KSK.左左尖号:
            case KSK.右右尖号: {
                if (.允许类型计算) {
                    return .编译二元运算类型节点剩余(0, type);
                }
            }
            default: {
                return type;
            }
        }
    }
    return type;
}
Klang节点_ 编译二元运算类型节点(int 优先级) {
    Klang节点_ 左侧 = .编译类型();
    return .编译二元运算类型节点剩余(优先级, 左侧);
}
Klang节点_ 编译二元运算类型节点剩余(int 优先级, Klang节点_ 左侧) {
    while(true) {
        .预扫描大于号();
        int 新优先级 = .获取二元运算符优先级(.令牌());
        bool 停止当前 = 新优先级 > 优先级;
        if (!停止当前) {
            break;
        }
        左侧 = .制作静态二元类型运算节点(左侧, .编译运算符(), .编译二元运算类型节点(新优先级));
    }
    return 左侧;
}
Klang节点_ 制作静态二元类型运算节点(Klang节点_ 左侧, KSK 运算符, Klang节点_ 右侧) {
    long 开始 = .获取节点开始();
    静态二元表达式类型节点_ n = 创建节点!(静态二元表达式类型节点_)(KSK.静态二元表达式类型节点, 左侧.开始);
    n.左侧 = 左侧;
    n.运算符 = 运算符;
    n.右侧 = 右侧;
    return .完成节点!(静态二元表达式类型节点_)(n, 开始);
}
Klang节点_ 编译联合类型(KSK kind, Klang节点_ delegate() 编译条件类型, KSK 运算符) {
    long 节点开始 = .获取节点开始();
    bool 前部运算符 = .编译可选的(运算符);
    Klang节点_ type = 编译条件类型();
    if (.令牌() == 运算符 || 前部运算符) {
        Klang节点_[] 类型组 = [type];
        while(.编译可选的(运算符)) {
            类型组 = .追加!(Klang节点_)(类型组, 编译条件类型());
        }
        联合类型_ n = 创建节点!(联合类型_)(kind);
        n.类型组 = .创建节点数组!(Klang节点_)(类型组, 节点开始);
        type = .完成节点!(联合类型_)(n, 节点开始);
    }
    return type;
}
Klang节点_ 编译联合类型或更高() {
    return .编译联合类型(KSK.联合类型, cast(Klang节点_ delegate())(·fd(&.编译类型运算或更高)), KSK.或号);
}
Klang节点_ 编译类型注释() {
    return .编译可选的(KSK.冒号) ? .编译类型() : ··null!(Klang节点_);
}
字面量类型_ 编译字面量类型类节点(bool 负号 = ··null!(bool)) {
    long 开始 = .获取节点开始();
    字面量类型_ n = 创建节点!(字面量类型_)(KSK.字面量类型);
    前缀一元表达式_ 负号表达式;
    if (负号) {
        负号表达式 = 创建节点!(前缀一元表达式_)(KSK.前缀一元表达式);
        负号表达式.运算符 = KSK.减号;
        .下个令牌();
    }
    Klang节点_ 表达式 = .令牌() == KSK.真_ || .令牌() == KSK.假_ ? .编译klang令牌节点!(KSK)(.令牌()) : .编译文本或数字字面量节点(.令牌());
    if (负号) {
        负号表达式.表达式 = 表达式;
        .完成节点!(前缀一元表达式_)(负号表达式, 表达式.开始);
        表达式 = 负号表达式;
    }
    n.字面量 = 表达式;
    return .完成节点!(字面量类型_)(n, 开始);
}
字面量类表达式基类_ 编译文本或数字字面量节点(KSK ksk) {
    if (ksk == KSK.数字字面量) {
        return .编译数字字面量表达式();
    }
    else {
        return .编译文本字面量表达式();
    }
}
Klang节点_ 编译非数组类型() {
    switch (.令牌()) {
        case KSK.类型_:
        case KSK.整数_:
        case KSK.通用_:
        case KSK.文本_:
        case KSK.文本8_:
        case KSK.文本16_:
        case KSK.文本32_:
        case KSK.真假_:
        case KSK.无值_:
        case KSK.空值_:
        case KSK.正量_:
        case KSK.小数_:
        case KSK.正整数_:
        case KSK.整数8_:
        case KSK.整数16_:
        case KSK.整数32_:
        case KSK.整数64_:
        case KSK.正整数8_:
        case KSK.正整数16_:
        case KSK.正整数32_:
        case KSK.正整数64_:
        case KSK.小数32_:
        case KSK.小数64_:
        case KSK.虚数32_:
        case KSK.虚数64_:
        case KSK.复数64_:
        case KSK.复数128_:
        case KSK.字符_:
        case KSK.字符8_:
        case KSK.字符16_:
        case KSK.字符32_:
        case KSK.字节_: {
            return .编译klang令牌节点!(KSK)(.令牌());
        }
        case KSK.减号: {
            return .向前看!(bool)(cast(bool delegate())(·fd(&.下个令牌是数值字面量))) ? .编译字面量类型类节点(/*负号*/ true) : .编译类型引用();
        }
        case KSK.数字字面量: {
            字面量类型_ 临时 = .编译字面量类型类节点();
            if (.编译可选的(KSK.波折号)) {
                字面量类型_ 临时2 = .尝试编译!(字面量类型_)(() { return .编译字面量类型类节点(false); });
                区间类型节点_ 区间类型节点 = 创建节点!(区间类型节点_)(KSK.区间类型节点);
                区间类型节点.区间开始 = 临时;
                区间类型节点.区间结束 = 临时2;
                return .完成节点!(区间类型节点_)(区间类型节点, 临时.开始);
            }
            else {
                return 临时;
            }
        }
        case KSK.无替换模板字面量:
        case KSK.文本字面量:
        case KSK.字符字面量:
        case KSK.真_:
        case KSK.假_: {
            return .编译字面量类型类节点();
        }
        case KSK.左括号: {
            return .编译括号类型();
        }
        case KSK.只读_: {
            long 节点开始 = .获取节点开始();
            类型限定类型_ tn = 创建节点!(类型限定类型_)(KSK.类型限定类型);
            .下个令牌();
            tn.限定符 = KSK.只读_;
            tn.类型 = .令牌() == KSK.左括号 ? .编译括号类型() : .编译类型();
            return .完成节点!(类型限定类型_)(tn, 节点开始);
        }
        case KSK.恒定_: {
            long 节点开始 = .获取节点开始();
            类型限定类型_ tn = 创建节点!(类型限定类型_)(KSK.类型限定类型);
            .下个令牌();
            tn.限定符 = KSK.恒定_;
            tn.类型 = .令牌() == KSK.左括号 ? .编译括号类型() : .编译类型();
            return .完成节点!(类型限定类型_)(tn, 节点开始);
        }
        case KSK.共享_: {
            long 节点开始 = .获取节点开始();
            类型限定类型_ tn = 创建节点!(类型限定类型_)(KSK.类型限定类型);
            .下个令牌();
            tn.限定符 = KSK.共享_;
            tn.类型 = .令牌() == KSK.左括号 ? .编译括号类型() : .编译类型();
            return .完成节点!(类型限定类型_)(tn, 节点开始);
        }
        case KSK.对象_:
        case KSK.结构_: {
            if (!.向前看!(bool)(cast(bool delegate())(·fd(&.应编译虚拟类型)))) {
                long 节点开始 = .获取节点开始();
                类型限定类型_ tn = 创建节点!(类型限定类型_)(KSK.类型限定类型);
                tn.限定符 = .令牌();
                .下个令牌();
                tn.类型 = .令牌() == KSK.左括号 ? .编译括号类型() : .编译类型();
                return .完成节点!(类型限定类型_)(tn, 节点开始);
            }
        }
        // 贯穿
        case KSK.函数_:
        case KSK.指针_: {
            return .编译klang令牌节点!(KSK)(.令牌());
        }
        case KSK.左方括号: {
            return .编译元组类型节点();
        }
        default: {
            return .编译类型引用();
        }
    }
}
bool 应编译虚拟类型() {
    if (.开始编译约束类型) {
        .下个令牌();
        return !.是类型的开始();
    }
    return false;
}
元组类型节点_ 编译元组类型节点() {
    long 节点开始 = .获取节点开始();
    元组类型节点_ tn = 创建节点!(元组类型节点_)(KSK.元组类型节点);
    .编译确定的(KSK.左方括号);
    Klang节点_ t = .编译类型();
    Klang节点_[] 类型组 = [t];
    while(.令牌() == KSK.逗号) {
        .下个令牌();
        类型组 = .追加!(Klang节点_)(类型组, .编译类型());
    }
    tn.类型组 = .创建节点数组!(Klang节点_)(类型组, t.开始);
    .编译确定的(KSK.右方括号);
    return .完成节点!(元组类型节点_)(tn, 节点开始);
}
Klang节点_ 编译类型引用() {
    long 开始 = .获取节点开始();
    类型引用_ n = 创建节点!(类型引用_)(KSK.类型引用);
    n.类型名称 = .编译实体名称(诊断集_.Type_expected);
    if (!.前面有换行符() && .令牌() == KSK.左尖括号) {
        .编译确定的(KSK.左尖括号);
        n.类型实参组 = .编译列表!(Klang节点_)(编译上下文_.类型实参组, cast(Klang节点_ delegate())(·fd(&.编译类型实参)));
        .编译确定的(KSK.右尖括号);
    }
    return .完成节点!(类型引用_)(n, 开始);
}
限定名_ 编译实体名称(诊断消息_ 诊断消息 = ··null!(诊断消息_)) {
    ··Klang节点_.Klang标识符_ id = .编译标识符(诊断消息);
    限定名_ 限定名 = new 限定名_(KSK.限定名, id.开始, id.结束);
    限定名.右侧 = id;
    while(.编译可选的(KSK.点号)) {
        限定名 = .创建限定名(限定名, .编译点的右侧());
    }
    return 限定名;
}
限定名_ 创建限定名(限定名_ 限定名, ··Klang节点_.Klang标识符_ 名称) {
    限定名_ n = 创建节点!(限定名_)(KSK.限定名);
    n.左侧 = 限定名;
    n.右侧 = 名称;
    return .完成节点!(限定名_)(n, 限定名.开始);
}
··Klang节点_.Klang标识符_ 编译点的右侧() {
    if (.前面有换行符() && .令牌是标识符或关键字(.令牌())) {
        bool 匹配模式 = .向前看!(bool)(cast(bool delegate())(·fd(&.下个令牌是标识符或关键字且在同一行)));
        if (匹配模式) {
            return .创建失踪节点!(··Klang节点_.Klang标识符_)(SK.标识符, /*报告错误在当前位置*/ true, 诊断集_.Identifier_expected);
        }
    }
    return .编译标识符();
}
bool 下个令牌是标识符或关键字且在同一行() {
    .下个令牌();
    return .令牌是标识符或关键字(.令牌()) && !.前面有换行符();
}
Klang节点_ 编译括号类型() {
    long 开始 = .获取节点开始();
    括号类型_ n = 创建节点!(括号类型_)(KSK.括号类型);
    .编译确定的(KSK.左括号);
    n.类型 = .编译类型();
    .编译确定的(KSK.右括号);
    return .完成节点!(括号类型_)(n, 开始);
}
Klang节点_ 编译函数或构建类型() {
    long 节点开始 = .获取节点开始();
    函数类型_ n = 创建节点!(函数类型_)(KSK.函数类型);
    .完成签名(KSK.等右尖号, 签名标志_.类型, n);
    return .完成节点!(函数类型_)(n, 节点开始);
}
基础节点.节点数组_!(类型形参_) 编译类型形参组(基础节点.节点_ n) {
    if (.令牌() == KSK.左尖括号) {
        .编译确定的(KSK.左尖括号);
        基础节点.节点数组_!(类型形参_) 列表 = .编译列表!(类型形参_)(编译上下文_.类型形参组, cast(类型形参_ delegate())(·fd(&.编译类型形参组成员)));
        .编译确定的(KSK.右尖括号);
        if ((列表 !is null) && (列表.原型 !is ··null!(类型形参_[])) && 列表.length > 0) {
            设置节点标志(n, 节点标志_.是泛型声明_);
        }
        return 列表;
    }
    return ··null!(基础节点.节点数组_!(类型形参_));
}
类型形参_ 编译类型形参组成员() {
    long 开始 = .获取节点开始();
    类型形参_ n = 创建节点!(类型形参_)(KSK.类型形参);
    n.名称 = .编译标识符();
    if (.编译可选的(KSK.冒号)) {
        .开始编译约束类型 = true;
        n.约束 = .编译类型();
        .开始编译约束类型 = false;
    }
    类型形参_ 结果 = .完成节点!(类型形参_)(n, 开始);
    逗号编译结果_ 逗号 = .编译逗号(() { return .令牌() == KSK.右尖括号; });
    if (逗号 == 逗号编译结果_.逗号后就结束_) {
        结果.后面是逗号 = true;
    }
    return 结果;
}
bool 编译形参列表(签名声明_ 签名节点, 签名标志_ 标志) {
    if (!.编译确定的(KSK.左括号)) {
        签名节点.形参组 = .创建失踪列表!(形参声明_)();
        return false;
    }
    签名节点.形参组 = .编译列表!(形参声明_)(编译上下文_.形参组, cast(形参声明_ delegate())(·fd(&.编译形参声明组)));
    return .编译确定的(KSK.右括号);
}
形参声明_ 编译形参声明组() {
    形参声明_ 结果 = .编译形参();
    逗号编译结果_ 逗号 = .编译逗号(() { return .令牌() == KSK.右括号; });
    if (逗号 == 逗号编译结果_.逗号后就结束_) {
        结果.后面是逗号 = true;
    }
    return 结果;
}
Klang节点_ 编译形参的类型() {
    .编译确定的(KSK.冒号, 诊断集_.应为声明的注释类型);
    return .编译类型();
}
Klang节点_ 编译初始化() {
    if (.编译可选的(KSK.等号) || .编译可选的(KSK.冒等号)) {
        return .编译赋值表达式或更高();
    }
    return ··null!(Klang节点_);
}
形参声明_ 编译形参() {
    long 开始 = .获取节点开始();
    形参声明_ n = 创建节点!(形参声明_)(KSK.形参声明);
    if (.令牌() == KSK.本体_) {
        n.名称 = .编译标识符();
        n.类型 = .编译形参的类型();
        return (cast(形参声明_)(.完成节点!(形参声明_)(n, 开始)));
    }
    n.修饰符 = .编译修饰符组();
    n.名称 = .编译标识符();
    if (.令牌() == KSK.问号) {
        .下个令牌();
        n.问号 = KSK.问号;
    }
    n.类型 = .编译形参的类型();
    n.初始化 = .编译初始化();
    形参声明_ 结果 = (cast(形参声明_)(.完成节点!(形参声明_)(n, 开始)));
    return 结果;
}
bool 类型具有阻止编译错误的箭头函数(Klang节点_ node) {
    switch (node.目标种类) {
        case KSK.类型引用: {
            类型引用_ n = 获取类型引用(node);
            if (n is ··null!(类型引用_)) {
                return true;
            }
            return 是失踪节点(n.类型名称);
        }
        case KSK.函数类型: {
            函数类型_ n = 获取函数类型(node);
            if (n is ··null!(函数类型_)) {
                return true;
            }
            return 是失踪列表!(形参声明_)(n.形参组) || .类型具有阻止编译错误的箭头函数(n.类型);
        }
        case KSK.类型列表: {
            类型列表_ n = 获取类型列表(node);
            if (n is ··null!(类型列表_)) {
                return true;
            }
            return 循环每个!(Klang节点_, bool)(n.类型组, (类型节点_ v, size_t _) { return .类型具有阻止编译错误的箭头函数(v); });
        }
        case KSK.括号类型: {
            括号类型_ n = 获取括号类型(node);
            if (n is ··null!(括号类型_)) {
                return true;
            }
            return .类型具有阻止编译错误的箭头函数(n.类型);
        }
        default: {
            return false;
        }
    }
}
bool 是函数类型的开始() {
    if (.令牌() == KSK.左尖括号) {
        return true;
    }
    return .令牌() == KSK.左括号 && .向前看!(bool)(cast(bool delegate())(·fd(&.是明确的函数类型开始)));
}
bool 是明确的函数类型开始() {
    .下个令牌();
    if (.令牌() == KSK.右括号 || .令牌() == KSK.三点号) {
        // ( )
        // ( ...
        return true;
    }
    if (.跳过形参开始()) {
        if (.令牌() == KSK.冒号 || .令牌() == KSK.等号 || .令牌() == KSK.问号 || .令牌() == KSK.等号) {
            // ( xxx :
            // ( xxx ,
            // ( xxx ?
            // ( xxx =
            return true;
        }
        if (.令牌() == KSK.右括号) {
            .下个令牌();
            if (.令牌() == KSK.等右尖号) {
                // ( xxx ) =>
                return true;
            }
            if (.令牌() == KSK.冒号) {
                return true;
            }
        }
    }
    return false;
}
bool 跳过形参开始() {
    if (.是标识符() || .令牌() == KSK.本体_) {
        .下个令牌();
        return true;
    }
    return false;
}
